2

I am still pretty new to Rust and I have this function:

Edit: Here is a newer version of the function with the same issue as far as I can tell

pub fn new_from_file_path(path: &str) -> Parser {
    let path_buf: PathBuf = PathBuf::from(path);
    let absolute_path: PathBuf = std::fs::canonicalize(path_buf).unwrap();
    let data: String = std::fs::read_to_string(absolute_path).unwrap();
    let clone = data.clone();

    let s_slice: &str = &clone[..];
    return Parser::new_from_string_data(s_slice);
}

Here is the implementation of the new_from_string_data() function

pub fn new_from_string_data(data: &str) -> Parser {
    let parser = Parser::new(data.chars());
    return parser;
}

This is the struct definition for parser :

pub struct Parser<'a> {
    tokenizer: Tokenizer<'a>,
}

Here is a screenshot of the error message I am getting

A screenshot of the error message Any help would be greatly appreciated, please also let me know if more information is needed.

Ömer Erden
  • 7,680
  • 5
  • 36
  • 45
  • Could you add the error message you got from trying to build this code? – Locke Aug 14 '20 at 02:07
  • Also if I had to guess, I would say it errors since the lifetime of `content` is not `'static` ends before `tokenizer`. – Locke Aug 14 '20 at 02:11
  • 3
    It's technically not possible to say for sure because the question does not contain a [mre], but I can *virtually guarantee* that `tokenizer` is storing a reference to `content`, and so when `content` is dropped at the end of the function `tokenizer` becomes invalidated. You cannot make something `'static` just by claiming it is `'static`; it has to *actually be* `'static` and `Chars` is not. You could look into [How can I store a Chars iterator in the same struct as the String it is iterating on?](/q/43952104/3650362) for another take on the same basic issue. – trent Aug 14 '20 at 02:26
  • @Locke see the revised question – Alvin Kuruvilla Aug 14 '20 at 12:22
  • My guess youre returning a reference to stack data, try passing data to parser making it accept String, so it will take the onwership of the data – geckos Aug 14 '20 at 12:33
  • Still not really possible to answer this without seeing the definition of `Tokenizer`. Did you write `Tokenizer` yourself or is it from some crate? – harmic Aug 15 '20 at 02:02
  • Welcome to Stack Overflow! It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. In the future, try to reproduce your error on the [Rust Playground](https://play.rust-lang.org/) if possible, otherwise in a brand new Cargo project, then edit your question to include the additional info. There are [Rust-specific MRE](https://stackoverflow.com/tags/rust/info) tips you can use to reduce your original code for posting here. Thanks! – mcarton Aug 15 '20 at 23:12
  • You should also include the error messages as text, since images aren't accessible and won't be indexed by search engines. – mcarton Aug 15 '20 at 23:12

2 Answers2

0

new_from_string_data function returns a Parser with the same lifetime as it's input argument data.

In the case of new_from_file_path, data is s_slice which is a slice of the string clone owned by the function new_from_file_path. Hence the returned Parser would reference clone which is destroyed when returning from the function new_from_file_path

Guillaume Gris
  • 2,135
  • 17
  • 34
0

str::chars() returns an iterator struct that requires an explicit lifetime as it (presumably, I haven't read the full struct definition myself) references the data passed to chars() (pub struct Chars<'a> { /* fields omitted */ }), just like your Parser struct, and you are generating the referenced variable(s) inside of new_from_file_path in the statement let clone = data.clone();.

I'd suggest simply adding a lifetime annotation to the function header so it reads as follows:

pub fn new_from_file_path<'a>(path: &'a str) -> Parser<'a> {...}

This wont complicate calling the function and tells the compiler that the returned Parser struct and its refrences should have the same lifetime as the data passed to the function.