Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nom's error is referencing data owned by the calling function #1706

Open
absoludity opened this issue Nov 3, 2023 · 0 comments
Open

Nom's error is referencing data owned by the calling function #1706

absoludity opened this issue Nov 3, 2023 · 0 comments

Comments

@absoludity
Copy link

absoludity commented Nov 3, 2023

Prerequisites

Here are a few things you should provide to help me understand the issue:

[package]
name = "repro_nom_error_issue"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nom = "7.1.3"

Test case

I've created an example with the work around at:

https://github.com/absoludity/repro_nom_error_issue/blob/df4e339accb4a4ddb40c9c781f1febca1b4dd73f/src/main.rs#L1-L26 :

use nom::bytes::complete::tag;
use nom::multi::many0;
use nom::IResult;
use std::error::Error;

fn parser(s: &str) -> IResult<&str, Vec<&str>> {
    many0(tag("abc"))(s)
}

fn main() -> Result<(), Box<dyn Error>> {
    // In actual code, the input comes as a string through:
    // let input = std::fs::read_to_string(INPUT_FILE_PATH)?
    let input = "abcabc123".to_string();

    // This following fails, without mapping the error:

    // let (remaining, parsed) = parser(&input)?;

    // Whereas it works fine if I ensure that the content of the error is owned
    // (which is internally cloning the &str content, I assume):
    let (remaining, parsed) = parser(&input).map_err(|e| e.map_input(|s| s.to_owned()))?;

    assert_eq!(remaining, "123");
    assert_eq!(parsed, vec!["abc", "abc"]);
    Ok(())
}

As you can see, it will compile fine if I map the error input to ensure it is owned, but without that map, the compiler won't compile as it appears the error content is referencing the original input data, which is owned by the calling function:

$ cargo run       
   Compiling repro_nom_error_issue v0.1.0 (/xxx/repro_nom_error_issue)
error[E0515]: cannot return value referencing local variable `input`
  --> src/main.rs:17:31
   |
17 |     let (remaining, parsed) = parser(&input)?;
   |                               ^^^^^^^------^^
   |                               |      |
   |                               |      `input` is borrowed here
   |                               returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.
error: could not compile `repro_nom_error_issue` (bin "repro_nom_error_issue") due to previous error

If this is an actual error that could be improved in nom (as opposed to me missing something obvious here), and you think it might be a good first issue, I'd be happy to jump in and fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant