neovim / nvim-lspconfig

Quickstart configs for Nvim LSP
Apache License 2.0
10.5k stars 2.07k forks source link

Lspconfig chooses wrong root for multi-crate rust project #1422

Closed yorickpeterse closed 2 years ago

yorickpeterse commented 2 years ago

Neovim version (nvim -v)

v0.6.0-dev+544-g7ae86c1d4

Vim (not Nvim) behaves the same?

No

Operating system/version

Linux

Terminal name/version

nvim-qt

$TERM environment variable

nvim-qt

Installation

Git

How to reproduce the issue

How to reproduce this exactly is something I'm still trying to figure out. The problem is as follows:

When using rust-analyzer, after a while old diagnostics stick around, even after fixing them. Looking at the LSP debug logs, the diagnostics are not produced by rust-analyzer, so it's not a case of a language server producing incorrect diagnostics.

Looking at the buffer cache for an affected buffer, it seems the stale diagnostics are produced for a different (perhaps older?) namespace. For example, the output is as follows:

{
  [15] = { {
      bufnr = 15,
      col = 0,
      end_col = 23,
      end_lnum = 10,
      lnum = 10,
      message = "remove the whole `use` item",
      namespace = 15,
      severity = 4,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 22,
                    line = 10
                  },
                  start = {
                    character = 4,
                    line = 10
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "original diagnostic"
            } }
        }
      }
    }, {
      bufnr = 15,
      col = 38,
      end_col = 55,
      end_lnum = 1,
      lnum = 1,
      message = "remove the unused import",
      namespace = 15,
      severity = 4,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 55,
                    line = 1
                  },
                  start = {
                    character = 40,
                    line = 1
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "original diagnostic"
            } }
        }
      }
    }, {
      bufnr = 15,
      col = 0,
      end_col = 30,
      end_lnum = 4,
      lnum = 4,
      message = "remove the whole `use` item",
      namespace = 15,
      severity = 4,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 29,
                    line = 4
                  },
                  start = {
                    character = 4,
                    line = 4
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "original diagnostic"
            } }
        }
      }
    }, {
      bufnr = 15,
      col = 4,
      end_col = 29,
      end_lnum = 4,
      lnum = 4,
      message = "unused import: `crate::tempfile::Tempfile`",
      namespace = 15,
      severity = 2,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 30,
                    line = 4
                  },
                  start = {
                    character = 0,
                    line = 4
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "remove the whole `use` item"
            } },
          tags = { 1 }
        }
      }
    }, {
      bufnr = 15,
      col = 4,
      end_col = 22,
      end_lnum = 10,
      lnum = 10,
      message = "unused import: `std::path::PathBuf`",
      namespace = 15,
      severity = 2,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 23,
                    line = 10
                  },
                  start = {
                    character = 0,
                    line = 10
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "remove the whole `use` item"
            } },
          tags = { 1 }
        }
      }
    }, {
      bufnr = 15,
      col = 40,
      end_col = 55,
      end_lnum = 1,
      lnum = 1,
      message = "unused import: `SOURCE_FILE_EXT`\n`#[warn(unused_imports)]` on by default",
      namespace = 15,
      severity = 2,
      source = "rustc",
      user_data = {
        lsp = {
          code = "unused_imports",
          relatedInformation = { {
              location = {
                range = {
                  end = {
                    character = 55,
                    line = 1
                  },
                  start = {
                    character = 38,
                    line = 1
                  }
                },
                uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"
              },
              message = "remove the unused import"
            } },
          tags = { 1 }
        }
      }
    } }
}

Here namespace 15 contains the stale diagnostics. New diagnostics in turn are produced under namespace 13. Using vim.diagnostic.get_namespace for these namespaces produces the following:

{
  name = "vim.lsp.rust_analyzer.1",
  opts = {},
  user_data = {
    sign_group = "vim.diagnostic.vim.lsp.rust_analyzer.1",
    underline_ns = 14
  }
}

{
  name = "vim.lsp.rust_analyzer.2",
  opts = {},
  user_data = {
    sign_group = "vim.diagnostic.vim.lsp.rust_analyzer.2",
    underline_ns = 16
  }
}

Based on the above, it seems that somewhere along the lines, NeoVim starts using a new namespace for new diagnostics, leaving the old diagnostics (in the old namespace) as-is. Clearing the old ones using vim.diagnostic.reset(15, 0) clears them up, and after that they don't show up (until you run into the problem again in a different buffer).

Expected behavior

Given language server X, I would expect it to always use the same namespace Y, ensuring diagnostics don't become stale.

Actual behavior

A new namespace appears to be used somewhere along the lines, resulting in old diagnostics not getting cleaned up when they are fixed.

yorickpeterse commented 2 years ago

Looking at the namespace names, which include the client ID, it seems the issue here is a new client ID being used, thus resulting in a new namespace. I wonder if this can happen when the language server crashes and restarts.

gpanders commented 2 years ago

It looks like the original client for rust-analyzer is being replaced by a new one, though I’m not sure why this would be happening. @neovim/lsp can you chime in on this?

mjlbach commented 2 years ago

Depends, if you close the client it should clean up the old namespace, unless there is a bug in the shutdown code. Are two running at the same time?

yorickpeterse commented 2 years ago

@mjlbach I only have one client for Rust configured (that being rust-analyzer), and I don't run anything like e.g. LspRestart. I wonder if this may happen when rust-analyzer panics, maybe that prevents neovim from detecting this/cleaning things up?

mjlbach commented 2 years ago

Maybe but we shouldn't auto-restart the language server (see later comment) and we should clean up when the client closes... If you can get a log from the repro we can check for panics/a call to start_client that would indicate the lspconfig autocommand triggered starting a second language server

yorickpeterse commented 2 years ago

@mjlbach The logs don't really show anything super interesting roughly around the time I got it to show stale diagnostics:

[DEBUG][2021-11-13 23:49:46] .../lua/vim/lsp.lua:912    "LSP[rust_analyzer]"    "client.request"    2   "textDocument/formatting"   {  options = {    insertSpaces = true,    tabSize = 4  },  textDocument = {    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"  }} <function 1>    10
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 14,  jsonrpc = "2.0",  method = "textDocument/formatting",  params = {    options = {      insertSpaces = true,      tabSize = 4    },    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 14,  jsonrpc = "2.0"}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didSave",  params = {    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 23,  jsonrpc = "2.0",  method = "window/workDoneProgress/create",  params = {    token = "rustAnalyzer/cargo check"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "begin",      title = "cargo check"    }  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:456    "server_request: callback result"   {  result = vim.NIL,  status = true}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 23,  jsonrpc = "2.0",  result = vim.NIL}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_variables",        message = "unused variable: `hir_mods`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "if this is intentional, prefix it with an underscore: `_hir_mods`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_hir_mods`",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "variant is never constructed: `Warning`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 11,            line = 31          },          start = {            character = 4,            line = 31          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `warn`",        range = {          end = {            character = 22,            line = 102          },          start = {            character = 18,            line = 102          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:49:46] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `bin_directory`",        range = {          end = {            character = 37,            line = 27          },          start = {            character = 4,            line = 27          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `test_directory`",        range = {          end = {            character = 38,            line = 33          },          start = {            character = 4,            line = 33          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`\n`#[warn(unused_imports)]` on by default",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`\n`#[warn(unused_imports)]` on by default",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      }, {        code = "unused_variables",        message = "unused variable: `source`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "if this is intentional, prefix it with an underscore: `_source`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_source`",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "associated function is never used: `without_message`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 26,            line = 21          },          start = {            character = 11,            line = 21          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "field is never read: `file`",        range = {          end = {            character = 14,            line = 9          },          start = {            character = 4,            line = 9          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `new`",        range = {          end = {            character = 14,            line = 13          },          start = {            character = 11,            line = 13          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `write`",        range = {          end = {            character = 16,            line = 39          },          start = {            character = 11,            line = 39          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `flush`",        range = {          end = {            character = 16,            line = 43          },          start = {            character = 11,            line = 43          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `path`",        range = {          end = {            character = 15,            line = 47          },          start = {            character = 11,            line = 47          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:49:47] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "end"    }  }}
[DEBUG][2021-11-13 23:50:35] .../lua/vim/lsp.lua:1067   "on_lines bufnr: 10, changedtick: 19, firstline: 1, lastline: 2, new_lastline: 2, old_byte_size: 39, old_utf32_size: 39, old_utf16_size: 39"    { "use crate::config::{BYTECODE_IMAGE_EXT};" }
[DEBUG][2021-11-13 23:50:36] .../lua/vim/lsp.lua:1067   "on_lines bufnr: 10, changedtick: 21, firstline: 1, lastline: 2, new_lastline: 2, old_byte_size: 41, old_utf32_size: 41, old_utf16_size: 41"    { "use crate::config::{BYTECODE_IMAGE_EXT, SOURCE_FILE_EXT};" }
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didChange",  params = {    contentChanges = { {        range = {          end = {            character = 37,            line = 1          },          start = {            character = 19,            line = 1          }        },        rangeLength = 18,        text = "{BYTECODE_IMAGE_EXT}"      }, {        range = {          end = {            character = 38,            line = 1          },          start = {            character = 38,            line = 1          }        },        rangeLength = 0,        text = ", SOURCE_FILE_EXT"      } },    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs",      version = 21    }  }}
[DEBUG][2021-11-13 23:50:37] .../lua/vim/lsp.lua:912    "LSP[rust_analyzer]"    "client.request"    2   "textDocument/formatting"   {  options = {    insertSpaces = true,    tabSize = 4  },  textDocument = {    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"  }} <function 1>    10
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 15,  jsonrpc = "2.0",  method = "textDocument/formatting",  params = {    options = {      insertSpaces = true,      tabSize = 4    },    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didChange",  params = {    contentChanges = {},    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs",      version = 21    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 15,  jsonrpc = "2.0"}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didSave",  params = {    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 24,  jsonrpc = "2.0",  method = "window/workDoneProgress/create",  params = {    token = "rustAnalyzer/cargo check"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "begin",      title = "cargo check"    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:456    "server_request: callback result"   {  result = vim.NIL,  status = true}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 24,  jsonrpc = "2.0",  result = vim.NIL}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_variables",        message = "unused variable: `hir_mods`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "if this is intentional, prefix it with an underscore: `_hir_mods`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_hir_mods`",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `bin_directory`",        range = {          end = {            character = 37,            line = 27          },          start = {            character = 4,            line = 27          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "variant is never constructed: `Warning`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 11,            line = 31          },          start = {            character = 4,            line = 31          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `warn`",        range = {          end = {            character = 22,            line = 102          },          start = {            character = 18,            line = 102          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `bin_directory`",        range = {          end = {            character = 37,            line = 27          },          start = {            character = 4,            line = 27          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `test_directory`",        range = {          end = {            character = 38,            line = 33          },          start = {            character = 4,            line = 33          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `SOURCE_FILE_EXT`\n`#[warn(unused_imports)]` on by default",        range = {          end = {            character = 55,            line = 1          },          start = {            character = 40,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 55,                  line = 1                },                start = {                  character = 38,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"            },            message = "remove the unused import"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the unused import",        range = {          end = {            character = 55,            line = 1          },          start = {            character = 38,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 55,                  line = 1                },                start = {                  character = 40,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs",    version = 21  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      }, {        code = "unused_variables",        message = "unused variable: `source`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "if this is intentional, prefix it with an underscore: `_source`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_source`",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "associated function is never used: `without_message`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 26,            line = 21          },          start = {            character = 11,            line = 21          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "field is never read: `file`",        range = {          end = {            character = 14,            line = 9          },          start = {            character = 4,            line = 9          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "field is never read: `file`",        range = {          end = {            character = 14,            line = 9          },          start = {            character = 4,            line = 9          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `new`",        range = {          end = {            character = 14,            line = 13          },          start = {            character = 11,            line = 13          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `write`",        range = {          end = {            character = 16,            line = 39          },          start = {            character = 11,            line = 39          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `flush`",        range = {          end = {            character = 16,            line = 43          },          start = {            character = 11,            line = 43          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `path`",        range = {          end = {            character = 15,            line = 47          },          start = {            character = 11,            line = 47          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:50:37] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "end"    }  }}
[DEBUG][2021-11-13 23:51:02] .../lua/vim/lsp.lua:1067   "on_lines bufnr: 10, changedtick: 24, firstline: 1, lastline: 2, new_lastline: 2, old_byte_size: 58, old_utf32_size: 58, old_utf16_size: 58"    { "use crate::config::{BYTECODE_IMAGE_EXT};" }
[DEBUG][2021-11-13 23:51:02] .../lua/vim/lsp.lua:1067   "on_lines bufnr: 10, changedtick: 26, firstline: 1, lastline: 2, new_lastline: 2, old_byte_size: 41, old_utf32_size: 41, old_utf16_size: 41"    { "use crate::config::BYTECODE_IMAGE_EXT;" }
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didChange",  params = {    contentChanges = { {        range = {          end = {            character = 55,            line = 1          },          start = {            character = 38,            line = 1          }        },        rangeLength = 17,        text = ""      }, {        range = {          end = {            character = 39,            line = 1          },          start = {            character = 19,            line = 1          }        },        rangeLength = 20,        text = "BYTECODE_IMAGE_EXT"      } },    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs",      version = 26    }  }}
[DEBUG][2021-11-13 23:51:03] .../lua/vim/lsp.lua:912    "LSP[rust_analyzer]"    "client.request"    2   "textDocument/formatting"   {  options = {    insertSpaces = true,    tabSize = 4  },  textDocument = {    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"  }} <function 1>    10
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 16,  jsonrpc = "2.0",  method = "textDocument/formatting",  params = {    options = {      insertSpaces = true,      tabSize = 4    },    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 16,  jsonrpc = "2.0"}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:339    "rpc.send"  {  jsonrpc = "2.0",  method = "textDocument/didSave",  params = {    textDocument = {      uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs"    }  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  id = 25,  jsonrpc = "2.0",  method = "window/workDoneProgress/create",  params = {    token = "rustAnalyzer/cargo check"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "begin",      title = "cargo check"    }  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:456    "server_request: callback result"   {  result = vim.NIL,  status = true}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:339    "rpc.send"  {  id = 25,  jsonrpc = "2.0",  result = vim.NIL}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/run.rs",    version = 26  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = {},    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_variables",        message = "unused variable: `hir_mods`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "if this is intentional, prefix it with an underscore: `_hir_mods`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_hir_mods`",        range = {          end = {            character = 20,            line = 38          },          start = {            character = 12,            line = 38          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 20,                  line = 38                },                start = {                  character = 12,                  line = 38                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/compiler.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "variant is never constructed: `Warning`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 11,            line = 31          },          start = {            character = 4,            line = 31          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `warn`",        range = {          end = {            character = 22,            line = 102          },          start = {            character = 18,            line = 102          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/diagnostics.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "constant is never used: `BYTECODE_EXT`",        range = {          end = {            character = 44,            line = 12          },          start = {            character = 0,            line = 12          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "constant is never used: `SRC_DIR`",        range = {          end = {            character = 39,            line = 15          },          start = {            character = 0,            line = 15          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `bin_directory`",        range = {          end = {            character = 37,            line = 27          },          start = {            character = 4,            line = 27          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "field is never read: `test_directory`",        range = {          end = {            character = 38,            line = 33          },          start = {            character = 4,            line = 33          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/compiler/src/config.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`\n`#[warn(unused_imports)]` on by default",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "unused_imports",        message = "unused import: `crate::command::run`\n`#[warn(unused_imports)]` on by default",        range = {          end = {            character = 23,            line = 1          },          start = {            character = 4,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 24,                  line = 1                },                start = {                  character = 0,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "remove the whole `use` item"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_imports",        message = "remove the whole `use` item",        range = {          end = {            character = 24,            line = 1          },          start = {            character = 0,            line = 1          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 23,                  line = 1                },                start = {                  character = 4,                  line = 1                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      }, {        code = "unused_variables",        message = "unused variable: `source`\n`#[warn(unused_variables)]` on by default",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "if this is intentional, prefix it with an underscore: `_source`"          } },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "unused_variables",        message = "if this is intentional, prefix it with an underscore: `_source`",        range = {          end = {            character = 14,            line = 105          },          start = {            character = 8,            line = 105          }        },        relatedInformation = { {            location = {              range = {                end = {                  character = 14,                  line = 105                },                start = {                  character = 8,                  line = 105                }              },              uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"            },            message = "original diagnostic"          } },        severity = 4,        source = "rustc"      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/command/test.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "associated function is never used: `without_message`\n`#[warn(dead_code)]` on by default",        range = {          end = {            character = 26,            line = 21          },          start = {            character = 11,            line = 21          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/error.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "field is never read: `file`",        range = {          end = {            character = 14,            line = 9          },          start = {            character = 4,            line = 9          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `new`",        range = {          end = {            character = 14,            line = 13          },          start = {            character = 11,            line = 13          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `write`",        range = {          end = {            character = 16,            line = 39          },          start = {            character = 11,            line = 39          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "textDocument/publishDiagnostics",  params = {    diagnostics = { {        code = "dead_code",        message = "field is never read: `file`",        range = {          end = {            character = 14,            line = 9          },          start = {            character = 4,            line = 9          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `new`",        range = {          end = {            character = 14,            line = 13          },          start = {            character = 11,            line = 13          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `write`",        range = {          end = {            character = 16,            line = 39          },          start = {            character = 11,            line = 39          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `flush`",        range = {          end = {            character = 16,            line = 43          },          start = {            character = 11,            line = 43          }        },        severity = 2,        source = "rustc",        tags = { 1 }      }, {        code = "dead_code",        message = "associated function is never used: `path`",        range = {          end = {            character = 15,            line = 47          },          start = {            character = 11,            line = 47          }        },        severity = 2,        source = "rustc",        tags = { 1 }      } },    uri = "file:///home/yorickpeterse/Projects/inko/inko/cli/src/tempfile.rs"  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "report",      message = "cli"    }  }}
[DEBUG][2021-11-13 23:51:03] .../vim/lsp/rpc.lua:446    "rpc.receive"   {  jsonrpc = "2.0",  method = "$/progress",  params = {    token = "rustAnalyzer/cargo check",    value = {      kind = "end"    }  }}

I'm now experimenting with rust-analyzer's own logging (per https://github.com/rust-analyzer/rust-analyzer/blob/86ebc36fa3a4924d169884b42a0d8286da0cb53e/docs/dev/README.md#logging).

yorickpeterse commented 2 years ago

I think I found out what the issue is, and it's not a crash (I think?):

My project consists of three crates (compiler, vm and cli). These are configured using Rust/Cargo workspaces. When I open a file in any of the projects on its own, everything is fine. If I then open a file in a different crate, it seems to result in a new client being produced. From this point forward, existing diagnostics are never cleared out. Here's a recording showing the issue:

asciicast

And the logs:

https://gist.github.com/YorickPeterse/1036caf54faccb66afb1ec43701525fa

mjlbach commented 2 years ago

Can you show LspInfo? If so, this is more of an lspconfig issue than core.

yorickpeterse commented 2 years ago

When there's only 1 client and all is working well:


 Language client log: /home/yorickpeterse/.cache/nvim/lsp.log
 Detected filetype:   rust

 1 client(s) attached to this buffer: 

 Client: rust_analyzer (id: 1, pid: 37099, bufnr: [12])
    filetypes:       rust
    autostart:       true
    root directory:  /home/yorickpeterse/Projects/inko/inko/compiler
    cmd:             rust-analyzer

 Configured servers list: null-ls, sumneko_lua, clangd, rust_analyzer, gopls, jedi_language_server

After opening a file in a different workspace crate, and a new client/namespace is used:


 Language client log: /home/yorickpeterse/.cache/nvim/lsp.log
 Detected filetype:   rust

 1 client(s) attached to this buffer: 

 Client: rust_analyzer (id: 2, pid: 37164, bufnr: [23])
    filetypes:       rust
    autostart:       true
    root directory:  /home/yorickpeterse/Projects/inko/inko/cli
    cmd:             rust-analyzer

 1 active client(s) not attached to this buffer: 

 Client: rust_analyzer (id: 1, pid: 37099, bufnr: [12])
    filetypes:       rust
    autostart:       true
    root directory:  /home/yorickpeterse/Projects/inko/inko/compiler
    cmd:             rust-analyzer

 Configured servers list: null-ls, sumneko_lua, clangd, rust_analyzer, gopls, jedi_language_server
mjlbach commented 2 years ago

Yep, lspconfig bug.

yorickpeterse commented 2 years ago

Looking at lspconfig, it seems to use Cargo.toml as the workspace root file:

https://github.com/neovim/nvim-lspconfig/blob/a96ab275dbe2827eec9467a86940c1bc48589c82/lua/lspconfig/rust_analyzer.lua#L18-L54

This won't work well I think for multi-crate projects, as each crate has its own Cargo.toml, but there's only one shared Cargo.lock. Perhaps it should find Cargo.lock and fall back to Cargo.toml if none could be found?

mjlbach commented 2 years ago

It doesn't use cargo.toml directly, it calls

'cargo metadata --no-deps --format-version 1 and pulls workspace_root out of that

yorickpeterse commented 2 years ago

OK I seem to be an idiot. Unknown to present-day me, I had this line in my rust-analyzer config:

root_dir = config.util.root_pattern('Cargo.toml', 'rustfmt.toml')

This line results in the root directory becoming that of the crate, not the root of all the crates. If I remove that line, it seems all is well.

I guess the moral of the story here is to not report bugs after midnight :man_facepalming:

mjlbach commented 2 years ago

Lmao its ok, we've all been there. LMK if there is something I should improve in the default lspconfig root pattern :)