Rust combine lifetime problem

#1
  1. I have no idea what I am doing. I have the following code:
pub struct FooParser<'a> {
    env: LanguageEnv<'a, combine::easy::Stream<&'a str>>,
}

impl <'a> FooParser<'a> {

    pub fn parens<P>(&self, parser: P) -> impl Parser<Input = combine::stream::easy::Stream<&'a str>, Output = P::Output>
        where
            P: Parser<Input = combine::stream::easy::Stream<&'a str>>,
    //    P::Input : Stream<Item = char>,
    {
        let t: BetweenChar<'a, 'a, P> = self.env.parens::<'a>(parser);
        t
    }
  1. It is giving me error of:
   |
87 |         let t: BetweenChar<'a, 'a, P> = self.env.parens::<'a>(parser);
   |                                                  ^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 82:5...

   |
82 | /     pub fn parens<P>(&self, parser: P) -> impl Parser<Input = combine::stream::easy::Stream<&'a str>, Output = P::Output>
83 | |         where
84 | |             P: Parser<Input = combine::stream::easy::Stream<&'a str>>,
85 | |     //    P::Input : Stream<Item = char>,
...  |
88 | |         t
89 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content

87 |         let t: BetweenChar<'a, 'a, P> = self.env.parens::<'a>(parser);
   |                                         ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 80:7...

   |
80 | impl <'a> FooParser<'a> {
   |       ^^
   = note: ...so that the types are compatible:
           expected &'a combine_language::LanguageEnv<'_, combine::stream::easy::Stream<&'a str>>
              found &combine_language::LanguageEnv<'a, combine::stream::easy::Stream<&'a str>>
  1. I have tried almost every option of 'a, 'b. Any idea wtf is going on and how to fix it?
#2

At a guess

pub fn parens<'f, P>(&'f self, parser: P) -> impl Parser<Input = combine::stream::easy::Stream<&'a str>, Output = P::Output> + 'f

Definitely seems complicated. Just replying without knowledge of LanguageEnv or its parens function. Some small snippet that can be run (same error) on play goes a long way being able to help.

#3

@jonh : I can create a minimal failure case. Is there a way to add a Cargo.toml dependencies to the Rust playground? I couldn’t figure out how to do that.

#4

Leveraging your suggestion,

    pub fn parens<'f, P>(&'f self, parser: P) -> impl Parser<Input = combine::stream::easy::Stream<&'a str>, Output = P::Output> + 'f
        where
            P: Parser<Input = combine::stream::easy::Stream<&'a str>> + 'a,
            'f: 'a
    {
        let e: &LanguageEnv<'a, combine::easy::Stream<&'a str>> = &self.env;
        let x: BetweenChar<'a, 'a, P> = e.parens(parser);
    }

appears to work. Thanks!

Nevertheless, is there a way to attach Cargo.toml dependencies to Rust playground? I am happy to create minimal failure cases, I just can’t figure out how to add dependencies.

#5

It is fixed (I think to top few hundred used crates.)
Can read file
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=770a17d89464b8980c2f38d84f1335f0

Only intended for quick code so service is free, more dependencies would just add extra burden.

Until someone wants to shift burden onto browser (like jslinux)

#6

@jonh

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e725f0708b6b4b7956e4b3a35779a341

Am I using it right? does not seem to include combine. :frowning:

#7

The Playground’s Source includes a Cargo.toml which is meant to be the base for playground projects. I’m not too sure, but according to this, there seems to be the first 218 top used crates. You might want to confirm that with @shepmaster though.

1 Like
#8

https://play.integer32.com/help#features-crates

The playground provides the top 100 most downloaded crates from crates.io, the crates from the Rust Cookbook, and all of their dependencies

However, the playground is still a great way to share your MCVE, even if it cannot be run on the playground. We track a list of steps to create a MCVE over on Stack Overflow (see “Producing a Minimal, Complete, Verifiable example for Rust code”) which can be useful to reduce your local code to something that could work in the playground.

1 Like
#9

@shepmaster : Any chance you can add nom, combine, combine-language, lalrpop ?

If you can’t because doing so would, out of fairness, involve adding every package everyone asks for, I completely understand.