0

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) 
2
  • does this help: stackoverflow.com/questions/32682876/…? Commented Feb 20, 2021 at 9:07
  • @KrishnaChaurasia, thank you but I don's get clear path between the answer and my case. all answer are just descriptions of the error[E0515]. I need how to workaround. For may case, what is an owned type to work well? Commented Feb 20, 2021 at 9:58

1 Answer 1

1

It looks you're cloning and then immediately passing a ref of the clone to parseExpr. In that case have you considered transferring ownership of tok to the method instead of passing a mutable ref, since you're cloning it anyway?

Basically changing

pub fn parseExpr<'a>(tok:&'a mut TokMuta<'a>, immuta:&TokImmuta<'a>,minrbp:usize) 

to

pub fn parseExpr<'a>(mut tok: TokMuta<'a>, immuta:&TokImmuta<'a>,minrbp:usize) 

and updating the call sites.

Rust Playground

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.