Cannot return value referencing function parameter `schema `

pub fn parse<'d, 's, P>(mut schema: &'s mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d>
where
    P: Pattern<'s> + Clone,
    's: 'd,
{
    // let mut schema = schema.clone();
    info!("validating schema...");
    schema.validate()?;

    info!("schema is validated");

    let result = match &schema.file_type {
        FileType::CSV => SVParser::new(',').parse(&mut schema, data),
        FileType::Separated { separator } => {
            SVParser::new(separator.clone()).parse(&mut schema, data)
        }
        FileType::Excel => ExcelParser.parse(&mut schema, data),
        FileType::FixedLength => FixedWidthParser.parse(&mut schema, data),
    };

    info!("parsed successfully!");

    result
}

The following code fails with two error messages,
on the last line: cannot return value referencing function parameter schema `

and on line SVParser::new(separator.clone()).parse(&mut schema, data): lifetime may not live long enough, consider adding the following bound: 'd: 's

what is the signature of the parse() function?

You'll get more/better replies if you supply something reproducible and/or supply the full output from cargo check. The signatures of the parse methods called may also be relevant.


At a guess, you're returning something that holds onto a reference or other lifetime-carrying struct from schema (involving lifetime 's), but you said you'd return lifetime 'd. If you follow the 'd: 's advice, in combination with the 's: 'd already present, they'll have to be the same lifetime.

I'm not sure why 's: 'd is present though.

And these parts:

pub fn parse<'d, 's, P>(mut schema: &'s mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d>
//                                  ^^^^^^^^^^^^^^^^^^^^^^
where
    P: Pattern<'s> + Clone,
//  ^^^^^^^^^^^^^^
    's: 'd,

Combine into a &'x mut Thing<'x>-like pattern which is probably problematic.

1 Like

here's the signature of parse method

pub trait Parse<'r> {
    fn parse<'d, P>(&self, schema: &'r mut ParseSchema<P>, data: &'r [u8]) -> ParseResult<'d>
    where
        'r: 'd;
}

the compiler output

error[E0515]: cannot return value referencing function parameter `schema`
  --> parser/src/parse_fn.rs:41:5
   |
36 |         FileType::FixedLength => FixedWidthParser.parse(&mut schema, data),
   |                                                         ----------- `schema` is borrowed here
...
41 |     result
   |     ^^^^^^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing function parameter `schema`
  --> parser/src/parse_fn.rs:41:5
   |
35 |         FileType::Excel => ExcelParser.parse(&mut schema, data),
   |                                              ----------- `schema` is borrowed here
...
41 |     result
   |     ^^^^^^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing function parameter `schema`
  --> parser/src/parse_fn.rs:41:5
   |
30 |         FileType::CSV => SVParser::new(',').parse(&mut schema, data),
   |                                                   ----------- `schema` is borrowed here
...
41 |     result
   |     ^^^^^^ returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.

did you spot the problem here? the lifetime of the data parameter is 'r but the return value contains 'd, which is different from the code snippets in the OP.

also, I don't know how you come up such complicated lifetime bounds, which is mostly unnecessary. although I don't have the full source code, but just guessing from the function signatures in the code snippets, I think you can probably get away with minimal as:

trait Parse {
	fn parse<'d, P>(&self, schema: &mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d>;
}
pub fn parse<'d, P>(mut schema: &mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d> {
    //...
}

adding the Pattern<'a> bounds, you just need:

trait Parse {
	fn parse<'d, 's, P>(&self, schema: &mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d>
	where P: Pattern<'s>;
}
pub fn parse<'d, 's, P>(mut schema: &mut ParseSchema<P>, data: &'d [u8]) -> ParseResult<'d>
where P: Pattern<'s> + Clone {
    //...
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.