I am trying to convert some short python code into Rust. It has a main recursive function.
But I am trapped in the following error which occurs near bottom of the pasted code. Reading the answers for the same error number seems difficult to interpret for my case. Please give some hint to fix the error.
cannot return value referencing temporary value returns a value referencing data owned by the current functionrustc(E0515) lib.rs(91, 63): temporary value created here lib.rs(94, 11): returns a value referencing data owned by the current function [Playground][2]
use std::collections::HashMap; #[derive(Eq,PartialEq,Clone,Debug)] pub struct TokImmuta<'a>{ tl:Vec<&'a str>,iops:&'a HashMap<&'a str,(Option<usize>,usize)> } #[derive(Eq,PartialEq,Copy,Clone,Debug)] pub struct TokMuta<'a>{ length:usize,pos:Option<usize>,current:&'a str } pub fn LBP<'a>(immuta:&TokImmuta<'a>,t:&str)->Option<usize>{return immuta.iops[t].0;} pub fn RBP<'a>(immuta:&TokImmuta<'a>,t:&str)->usize{return immuta.iops[t].1;} pub fn newTok2<'a>(ts:&'a str,iops:&'a mut HashMap<&'a str,(Option<usize>,usize)>)->( TokMuta<'a>,TokImmuta<'a>){ let tl:Vec<&str>=ts.split(" ").collect(); let tl_len=tl.len(); iops.insert("$END",(None,0)); ( TokMuta{ length : tl_len, pos : None, current : "$BEGIN", }, TokImmuta{ tl : tl, iops : iops, }, ) } pub fn Next<'a>(muta:&mut TokMuta<'a>,immuta:&TokImmuta<'a>)->&'a str{ if muta.current == "$PRE" { assert!(muta.pos!=None); muta.current = immuta.tl[muta.pos.unwrap()]; } else if immuta.iops.contains_key(muta.current) && RBP(immuta,muta.current) == 100{ muta.current = "$POST" } else { muta.pos=if muta.pos==None{Some(0)}else{Some(muta.pos.unwrap() + 1)}; if muta.pos.unwrap() >= muta.length { muta.current = "$END" } else { let atok = immuta.tl[muta.pos.unwrap()]; let lbp_atok=LBP(immuta,atok); if immuta.iops.contains_key(atok) && (lbp_atok!=None && lbp_atok.unwrap() == 100) { muta.current = "$PRE"; } else { muta.current = atok; } } } return muta.current; } pub fn TokSeq<'a>(muta:&mut TokMuta<'a>,immuta:TokImmuta<'a>)->String{ let mut s = muta.current.to_string(); while &muta.current != &"$END"{ s = format!("{} {}",s,Next(muta,&immuta)); } return s.to_string() } //===================================== use std::rc::Rc; #[derive(Debug)] pub struct Sexp<'a>{op:&'a str,left:Eexp<'a>,right:Eexp<'a>} #[derive(Debug)] pub enum Eexp<'a>{S(&'a str),C(Rc<Sexp<'a>>)} //===================================== pub fn parseExpr<'a>(tok:&'a mut TokMuta<'a>,immuta:&TokImmuta<'a>,minrbp:usize)->Eexp<'a>{ let mut s = Eexp::S(Next(tok, &immuta)); let mut n = Next(tok, &immuta); loop { let tok_lbp_n= if let Some(xxx)=LBP(&immuta,n){xxx as isize}else{-1}; if (minrbp as isize) >= tok_lbp_n { break } s=Eexp::C(Rc::new(Sexp{op:n,left:s,right:parseExpr(&mut tok.clone(),immuta,RBP(&immuta,n))})); n = tok.current.clone() ; } //////////////////////////////////////////////////////////////////// //ERROR //////////////////////////////////////////////////////////////////// return s //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// } pub fn PL2LL(pl:Eexp)->String { let s =match pl{ Eexp::C(rc)=> { format!("( {} {:#?} {:#?} )",rc.op,rc.left,rc.right)