Borrowed value does not live long enough stdin

From the following code I am getting: borrowed value does not live long enough..., Can someone help me fix it? I have tried a lot without success :frowning:

use std::io::{BufRead, stdin, stdout, StdinLock, StdoutLock, BufWriter, Write};

fn main() {
  let mut io = IO::new();
  let n = io.read::<String>();
  io.write(&n);
}

struct IO<'a> {
  cin: StdinLock<'a>,
  cout: BufWriter<StdoutLock<'a>>,
  line: String,
  line_buf: std::str::SplitWhitespace<'a>,
}

impl<'a> IO<'a> {
  pub fn new() -> Self {
    Self { cin: stdin().lock(), cout: BufWriter::new(stdout().lock()), line_buf: "".split_whitespace(), line: String::from("") }
  }
  
  pub fn read<T: std::str::FromStr>(&'a mut self) -> T {
    let token = match self.line_buf.next() {
      Some(value) => value,
      None => {
        self.cin.read_line(&mut self.line).expect("Error reading line");
        self.line_buf = self.line.split_whitespace();
        self.line_buf.next().expect("Error reading next token")
      }
    };
    return token.trim().parse().ok().expect("Failed to parse");
  }
  
  fn write(&'a mut self, msg: &str) -> () {
    write!(&mut self.cout, "{}", msg).ok();
  }
}

Error:

error[E0597]: `io` does not live long enough
 --> src/bin/competitive_programming_template.rs:5:11
  |
5 |   let n = io.read::<String>();
  |           ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
6 |   io.write(&n);
7 | }
  | -
  | |
  | `io` dropped here while still borrowed
  | borrow might be used here, when `io` is dropped and runs the destructor for type `IO<'_>`

You shouldn't use &'a mut self, but instead &mut self. &'a mut self adds a constraint to how long self lives that isn't satisfiable due to &'a mut being invariant in 'a.

If I do as you say I then get this other error:

error: lifetime may not live long enough
  --> src/bin/competitive_programming_template.rs:26:25
   |
16 | impl<'a> IO<'a> {
   |      -- lifetime `'a` defined here
...
21 |   pub fn read<T: std::str::FromStr>(&mut self) -> T {
   |                                     - let's call the lifetime of this reference `'1`
...
26 |         self.line_buf = self.line.split_whitespace();
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`

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

I see. Looks like you are trying to use a self-referential type. Rust doesn't have native support for it. You could try using a crate like ouroboros. I haven't used it myself though.

oh sad, thanks for trying anyways, hopefully someone else knows how to solve my issue :frowning:

You can track state instead.

I didn't do the leg work, but also consider having read return an io::Result instead of panicking; aside from reading the line, your failure cases are UnexpectedEof and InvalidData.

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.