1

I'm getting an error that "xo" and the string literal in the vector of vectors have different lifetimes. I was able to find a workaround by converting the literals to Strings via to_string() but I still would like to understand this error.

fn main() {
    let mut tic_tac = vec![
        vec!["[ ]", "[ ]", "[ ]"],
        vec!["[ ]", "[ ]", "[ ]"],
        vec!["[ ]", "[ ]", "[ ]"],
    ];

    let letter = "[x]";

    make_move(&letter, 1, &mut tic_tac);
    make_move(&letter, 4, &mut tic_tac);
}

fn make_move(xo: &str, position: i32, board: &mut Vec<Vec<&str>>) {
    if position < 4 && position <= 1 {
        match position {
            1 => board[0][0] = xo,
            2 => board[0][1] = xo,
            3 => board[0][2] = xo,
            _ => (),
        }
    }
}
error[E0623]: lifetime mismatch
  --> src/main.rs:18:32
   |
15 | fn make_move(xo: &str, position: i32, board: &mut Vec<Vec<&str>>) {
   |                  ----                                     ----
   |                  |
   |                  these two types are declared with different lifetimes...
...
18 |             1 => board[0][0] = xo,
   |                                ^^ ...but data from `xo` flows into `board` here
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ckiller
  • 39
  • 1
  • 3
  • 1
    All literals are of type `&'static str`, but not all `&'static str`s are literals. `xo` is not a string literal. You may want to read [What does the word "literal" mean?](https://stackoverflow.com/questions/485119/what-does-the-word-literal-mean) – trent Aug 08 '18 at 18:03

1 Answers1

2

Your function doesn't know that it will only be called with string literals. You can see this by deleting the entire body of main — it doesn't matter. If you take the time to create a Minimal, Complete, and Verifiable example, you would have discovered this for yourself.

Due to lifetime elision, the function is effectively defined as:

fn make_move<'a, 'b>(xo: &'a str, position: i32, board: &mut Vec<Vec<&'b str>>) 

Indeed, the two lifetimes have no relation to each other and you get the error.

Saying they are the same lifetime fixes it:

fn make_move<'a>(xo: &'a str, position: i32, board: &mut Vec<Vec<&'a str>>)

As does saying that the value being saved in the board is 'static:

fn make_move(xo: &'static str, position: i32, board: &mut Vec<Vec<&str>>)
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I see, each parameter that is a reference gets its own lifetime parameter. A function with two parameters gets two separate lifetime parameters. In the case of what im doing, lifetimes have to match that's why we have to specify the same lifetimes for the references correct? this is also to avoid dangling references? – Ckiller Aug 10 '18 at 17:17