1
votes

I'm trying to use the code I found here with some problems, basically it's a borrowing error using some macros, the error:

 Compiling playground v0.0.1 (file:///playground)
error[E0597]: `body` does not live long enough
  --> src/main.rs:12:3
   |
6  |            let raw_structure = borrow_function(&body);
   |                                                 ---- borrow occurs here
...
12 |        }
   |        ^ `body` dropped here while still borrowed
...
31 |             let body = get_body_as!(&str, "Hello", function1);
   |                        -------------------------------------- in this macro invocation
32 |             println!("Hello");
33 | }
   | -  borrowed value needs to live until here

I manage to create a Minimal, Complete, and Verifiable example, I was thinking that a solution would be to transform the macros into functions, but I'm not completely sure how to do that either (Playground ):

macro_rules! get_body_as {
    ($structure:ty, $req:expr, $error_fn:ident) => {
        {
            let body = get_body!($req, $error_fn);

            let raw_structure = borrow_function(&body);

            match raw_structure {
                Ok(structure) => structure,
                Err(error) => "Error"
            }
        }
    }
}

macro_rules! get_body {
    ($req:expr, $error_fn:ident) => {
        {
            let mut payload = String::new();

            payload
        }
    }
}

fn borrow_function(s: &str) -> Result<&str, &str> {
    Ok(s)
}
fn main() {
    let function1 = |s: &str| s;
    let body = get_body_as!(&str, "Hello", function1);
    println!("Hello");
}
1
Please post a minimal example containing the relevant part of the code in the question itself. See minimal reproducible example.interjay
@interjay I'm a Rust newbie and this project use a lot of crates, so it's no easy for me to create the Minimal Complete and Verifiable example, I'll try to reformulate the questionWerner Echezuria
@interjay I've manage to create the Minmal, Complete and Verifiable example (I think this fills the rule), any help will be greatly appreciate it.Werner Echezuria

1 Answers

1
votes

The problem is that you are trying to return a reference to a body variable from a block which owns the body variable, but body is to be dropped at the end of that block, so the reference would outlive the data it references.

If you want your example to compile, you can alter your code so that body is declared within the main function using ident parameter added to get_body_as macro:

macro_rules! get_body_as {
    ($structure:ty, $req:expr, $error_fn:ident, $body: ident) => {
            let $body = get_body!($req, $error_fn);

            let raw_structure = borrow_function(&$body);

            match raw_structure {
                Ok(structure) => structure,
                Err(error) => "Error"
            }
    }
}

macro_rules! get_body {
    ($req:expr, $error_fn:ident) => {
        {
            let mut payload = String::new();

            payload
        }
    }
}

fn borrow_function(s: &str) -> Result<&str, &str> {
    Ok(s)
}

fn main() {
    let function1 = |s: &str| s;
    get_body_as!(&str, "Hello", function1, body);
    println!("Hello");
}

This example compiles, but still has warnings about unused variables, I have made only minimal changes for compilation to succeed.