Repository: rust-analyzer/rust-analyzer
Pull request #6571 (2020-11-17 10:52:02)

Cleanup project model
bors r+
🤖


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 09215a37a2..715a809789 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -852,9 +852,9 @@ dependencies = [
 
 [[package]]
 name = "lsp-server"
-version = "0.5.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b18dfe0e4a380b872aa79d8e0ee6c3d7a9682466e84b83ad807c88b3545f79"
+checksum = "9c85acaf36c53bf15da2b8b35afeea56747707261f59eb0b77229081dd72b04e"
 dependencies = [
  "crossbeam-channel 0.5.0",
  "log",
@@ -864,9 +864,9 @@ dependencies = [
 
 [[package]]
 name = "lsp-types"
-version = "0.83.1"
+version = "0.83.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4e79f39834b97271f9f5ecec573e42c7d9c5bdbd2620b30a851054ece6aab6d"
+checksum = "25e0bd4b95038f2c23bda332ba0ca684e8dda765db1f9bdb63dc4c3e01f3b456"
 dependencies = [
  "base64",
  "bitflags",
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index 31907ed980..98ba372ad8 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -225,7 +225,10 @@ impl CrateGraph {
         to: CrateId,
     ) -> Result<(), CyclicDependenciesError> {
         if self.dfs_find(from, to, &mut FxHashSet::default()) {
-            return Err(CyclicDependenciesError);
+            return Err(CyclicDependenciesError {
+                from: (from, self[from].display_name.clone()),
+                to: (to, self[to].display_name.clone()),
+            });
         }
         self.arena.get_mut(&from).unwrap().add_dep(name, to);
         Ok(())
@@ -421,7 +424,20 @@ impl fmt::Display for ParseEditionError {
 impl std::error::Error for ParseEditionError {}
 
 #[derive(Debug)]
-pub struct CyclicDependenciesError;
+pub struct CyclicDependenciesError {
+    from: (CrateId, Option<CrateDisplayName>),
+    to: (CrateId, Option<CrateDisplayName>),
+}
+
+impl fmt::Display for CyclicDependenciesError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let render = |(id, name): &(CrateId, Option<CrateDisplayName>)| match name {
+            Some(it) => format!("{}({:?})", it, id),
+            None => format!("{:?}", id),
+        };
+        write!(f, "cyclic deps: {} -> {}", render(&self.from), render(&self.to))
+    }
+}
 
 #[cfg(test)]
 mod tests {
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs
index b0e8863f6a..f0a43eaf6b 100644
--- a/crates/project_model/src/sysroot.rs
+++ b/crates/project_model/src/sysroot.rs
@@ -37,7 +37,7 @@ impl Sysroot {
     pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ {
         // core is added as a dependency before std in order to
         // mimic rustcs dependency order
-        vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?)))
+        ["core", "alloc", "std"].iter().filter_map(move |&it| Some((it, self.by_name(it)?)))
     }
 
     pub fn proc_macro(&self) -> Option<SysrootCrate> {
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 9ebb0a811b..dbf1dc5bfa 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -12,8 +12,8 @@ use proc_macro_api::ProcMacroClient;
 use rustc_hash::{FxHashMap, FxHashSet};
 
 use crate::{
-    cargo_workspace, cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoWorkspace, ProjectJson,
-    ProjectManifest, Sysroot, TargetKind,
+    cargo_workspace, cfg_flag::CfgFlag, sysroot::SysrootCrate, utf8_stdout, CargoConfig,
+    CargoWorkspace, ProjectJson, ProjectManifest, Sysroot, TargetKind,
 };
 
 /// `PackageRoot` describes a package root folder.
@@ -70,12 +70,8 @@ impl ProjectWorkspace {
                     format!("Failed to deserialize json file {}", project_json.display())
                 })?;
                 let project_location = project_json.parent().unwrap().to_path_buf();
-                let project = ProjectJson::new(&project_location, data);
-                let sysroot = match &project.sysroot_src {
-                    Some(path) => Some(Sysroot::load(path)?),
-                    None => None,
-                };
-                ProjectWorkspace::Json { project, sysroot }
+                let project_json = ProjectJson::new(&project_location, data);
+                ProjectWorkspace::load_inline(project_json)?
             }
             ProjectManifest::CargoToml(cargo_toml) => {
                 let cargo_version = utf8_stdout({
@@ -150,43 +146,38 @@ impl ProjectWorkspace {
                     })
                 }))
                 .collect::<Vec<_>>(),
-            ProjectWorkspace::Cargo { cargo, sysroot, rustc } => {
-                let roots = cargo
-                    .packages()
-                    .map(|pkg| {
-                        let is_member = cargo[pkg].is_member;
-                        let pkg_root = cargo[pkg].root().to_path_buf();
-
-                        let mut include = vec![pkg_root.clone()];
-                        include.extend(cargo[pkg].out_dir.clone());
-
-                        let mut exclude = vec![pkg_root.join(".git")];
-                        if is_member {
-                            exclude.push(pkg_root.join("target"));
-                        } else {
-                            exclude.push(pkg_root.join("tests"));
-                            exclude.push(pkg_root.join("examples"));
-                            exclude.push(pkg_root.join("benches"));
-                        }
-                        PackageRoot { is_member, include, exclude }
-                    })
-                    .chain(sysroot.crates().map(|krate| PackageRoot {
+            ProjectWorkspace::Cargo { cargo, sysroot, rustc } => cargo
+                .packages()
+                .map(|pkg| {
+                    let is_member = cargo[pkg].is_member;
+                    let pkg_root = cargo[pkg].root().to_path_buf();
+
+                    let mut include = vec![pkg_root.clone()];
+                    include.extend(cargo[pkg].out_dir.clone());
+
+                    let mut exclude = vec![pkg_root.join(".git")];
+                    if is_member {
+                        exclude.push(pkg_root.join("target"));
+                    } else {
+                        exclude.push(pkg_root.join("tests"));
+                        exclude.push(pkg_root.join("examples"));
+                        exclude.push(pkg_root.join("benches"));
+                    }
+                    PackageRoot { is_member, include, exclude }
+                })
+                .chain(sysroot.crates().map(|krate| PackageRoot {
+                    is_member: false,
+                    include: vec![sysroot[krate].root_dir().to_path_buf()],
+                    exclude: Vec::new(),
+                }))
+                .chain(rustc.into_iter().flat_map(|rustc| {
+                    rustc.packages().map(move |krate| PackageRoot {
                         is_member: false,
-                        include: vec![sysroot[krate].root_dir().to_path_buf()],
+                        include: vec![rustc[krate].root().to_path_buf()],
                         exclude: Vec::new(),
-                    }));
-                if let Some(rustc_packages) = rustc {
-                    roots
-                        .chain(rustc_packages.packages().map(|krate| PackageRoot {
-                            is_member: false,
-                            include: vec![rustc_packages[krate].root().to_path_buf()],
-                            exclude: Vec::new(),
-                        }))
-                        .collect()
-                } else {
-                    roots.collect()
-                }
-            }
+                    })
+                }))
+                .collect(),
         }
     }
 
@@ -258,18 +249,14 @@ impl ProjectWorkspace {
                     if let Some(&from) = crates.get(&from) {
                         if let Some((public_deps, _proc_macro)) = &sysroot_dps {
                             for (name, to) in public_deps.iter() {
-                                if let Err(_) = crate_graph.add_dep(from, name.clone(), *to) {
-                                    log::error!("cyclic dependency on {} for {:?}", name, from)
-                                }
+                                add_dep(&mut crate_graph, from, name.clone(), *to)
                             }
                         }
 
                         for dep in &krate.deps {
                             let to_crate_id = dep.crate_id;
                             if let Some(&to) = crates.get(&to_crate_id) {
-                                if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
-                                    log::error!("cyclic dependency {:?} -> {:?}", from, to);
-                                }
+                                add_dep(&mut crate_graph, from, dep.name.clone(), to)
                             }
                         }
                     }
@@ -308,16 +295,12 @@ impl ProjectWorkspace {
                             }
                             if cargo[tgt].is_proc_macro {
                                 if let Some(proc_macro) = libproc_macro {
-                                    if let Err(_) = crate_graph.add_dep(
+                                    add_dep(
+                                        &mut crate_graph,
                                         crate_id,
                                         CrateName::new("proc_macro").unwrap(),
                                         proc_macro,
-                                    ) {
-                                        log::error!(
-                                            "cyclic dependency on proc_macro for {}",
-                                            &cargo[pkg].name
-                                        )
-                                    }
+                                    );
                                 }
                             }
 
@@ -332,21 +315,12 @@ impl ProjectWorkspace {
                             // cargo metadata does not do any normalization,
                             // so we do it ourselves currently
                             let name = CrateName::normalize_dashes(&name);
-                            if to != from && crate_graph.add_dep(from, name, to).is_err() {
-                                log::error!(
-                                    "cyclic dependency between targets of {}",
-                                    &cargo[pkg].name
-                                )
+                            if to != from {
+                                add_dep(&mut crate_graph, from, name, to);
                             }
                         }
                         for (name, krate) in public_deps.iter() {
-                            if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
-                                log::error!(
-                                    "cyclic dependency on {} for {}",
-                                    name,
-                                    &cargo[pkg].name
-                                )
-                            }
+                            add_dep(&mut crate_graph, from, name.clone(), *krate);
                         }
                     }
                 }
@@ -358,13 +332,7 @@ impl ProjectWorkspace {
                         let name = CrateName::new(&dep.name).unwrap();
                         if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
                             for &from in pkg_crates.get(&pkg).into_iter().flatten() {
-                                if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
-                                    log::error!(
-                                        "cyclic dependency {} -> {}",
-                                        &cargo[pkg].name,
-                                        &cargo[dep.pkg].name
-                                    )
-                                }
+                                add_dep(&mut crate_graph, from, name.clone(), to)
                             }
                         }
                     }
@@ -400,15 +368,7 @@ impl ProjectWorkspace {
                                 pkg_to_lib_crate.insert(pkg, crate_id);
                                 // Add dependencies on the core / std / alloc for rustc
                                 for (name, krate) in public_deps.iter() {
-                                    if let Err(_) =
-                                        crate_graph.add_dep(crate_id, name.clone(), *krate)
-                                    {
-                                        log::error!(
-                                            "cyclic dependency on {} for {}",
-                                            name,
-                                            &cargo[pkg].name
-                                        )
-                                    }
+                                    add_dep(&mut crate_graph, crate_id, name.clone(), *krate);
                                 }
                                 rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
                             }
@@ -421,13 +381,7 @@ impl ProjectWorkspace {
                             let name = CrateName::new(&dep.name).unwrap();
                             if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
                                 for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() {
-                                    if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
-                                        log::error!(
-                                            "cyclic dependency {} -> {}",
-                                            &rustc_workspace[pkg].name,
-                                            &rustc_workspace[dep.pkg].name
-                                        )
-                                    }
+                                    add_dep(&mut crate_graph, from, name.clone(), to);
                                 }
                             }
                         }
@@ -443,13 +397,7 @@ impl ProjectWorkspace {
                                     continue;
                                 }
                                 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
-                                    if let Err(_) = crate_graph.add_dep(from, name.clone(), to) {
-                                        log::error!(
-                                            "cyclic dependency {} -> {}",
-                                            &cargo[pkg].name,
-                                            &rustc_workspace[dep].name
-                                        )
-                                    }
+                                    add_dep(&mut crate_graph, from, name.clone(), to);
                                 }
                             }
                         }
@@ -520,19 +468,18 @@ fn sysroot_to_crate_graph(
 ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
     let mut cfg_options = CfgOptions::default();
     cfg_options.extend(get_rustc_cfg_options(target));
-    let sysroot_crates: FxHashMap<_, _> = sysroot
+    let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = sysroot
         .crates()
         .filter_map(|krate| {
             let file_id = load(&sysroot[krate].root)?;
 
             let env = Env::default();
             let proc_macro = vec![];
-            let name = CrateName::new(&sysroot[krate].name)
-                .expect("Sysroot crates' names do not contain dashes");
+            let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone());
             let crate_id = crate_graph.add_crate_root(
                 file_id,
                 Edition::Edition2018,
-                Some(name.into()),
+                Some(display_name),
                 cfg_options.clone(),
                 env,
                 proc_macro,
@@ -545,9 +492,7 @@ fn sysroot_to_crate_graph(
         for &to in sysroot[from].deps.iter() {
             let name = CrateName::new(&sysroot[to].name).unwrap();
             if let (Some(&from), Some(&to)) = (sysroot_crates.get(&from), sysroot_crates.get(&to)) {
-                if let Err(_) = crate_graph.add_dep(from, name, to) {
-                    log::error!("cyclic dependency between sysroot crates")
-                }
+                add_dep(crate_graph, from, name, to);
             }
         }
     }
@@ -588,3 +533,9 @@ fn get_rustc_cfg_options(target: Option<&str>) -> Vec<CfgFlag> {
 
     res
 }
+
+fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) {
+    if let Err(err) = graph.add_dep(from, name, to) {
+        log::error!("{}", err)
+    }
+}
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 56c51486f2..d25c4bf837 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -21,7 +21,7 @@ env_logger = { version = "0.8.1", default-features = false }
 itertools = "0.9.0"
 jod-thread = "0.1.0"
 log = "0.4.8"
-lsp-types = { version = "0.83.1", features = ["proposed"] }
+lsp-types = { version = "0.83.0", features = ["proposed"] }
 parking_lot = "0.11.0"
 pico-args = "0.3.1"
 oorandom = "11.1.2"
@@ -31,7 +31,7 @@ serde_json = "1.0.48"
 threadpool = "1.7.1"
 rayon = "1.5"
 mimalloc = { version = "0.1.19", default-features = false, optional = true }
-lsp-server = "0.5.0"
+lsp-server = "0.4.0"
 tracing = "0.1"
 tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
 tracing-tree = { version = "0.1.4" }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index c7203451ca..9a88700534 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -62,7 +62,6 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
             prepare_provider: Some(true),
             work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
         })),
-        on_type_rename_provider: None,
         document_link_provider: None,
         color_provider: None,
         execute_command_provider: None,
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 93bef5c8b4..15145415b3 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -55,8 +55,8 @@ fn location_naive(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Lo
 
     // FIXME: this doesn't handle UTF16 offsets correctly
     let range = lsp_types::Range::new(
-        lsp_types::Position::new(span.line_start as u32 - 1, span.column_start as u32 - 1),
-        lsp_types::Position::new(span.line_end as u32 - 1, span.column_end as u32 - 1),
+        lsp_types::Position::new(span.line_start as u64 - 1, span.column_start as u64 - 1),
+        lsp_types::Position::new(span.line_end as u64 - 1, span.column_end as u64 - 1),
     );
 
     lsp_types::Location { uri, range }
diff --git a/crates/rust-analyzer/src/document.rs b/crates/rust-analyzer/src/document.rs
index cf091510ff..04c7ee150a 100644
--- a/crates/rust-analyzer/src/document.rs
+++ b/crates/rust-analyzer/src/document.rs
@@ -6,11 +6,11 @@
 /// client notifications.
 #[derive(Debug, Clone)]
 pub(crate) struct DocumentData {
-    pub(crate) version: i32,
+    pub(crate) version: Option<i64>,
 }
 
 impl DocumentData {
-    pub(crate) fn new(version: i32) -> Self {
-        DocumentData { version }
+    pub(crate) fn new(version: i64) -> Self {
+        DocumentData { version: Some(version) }
     }
 }
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index defe11c553..63c70a09d8 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -263,9 +263,9 @@ impl GlobalStateSnapshot {
         self.vfs.read().1[&id]
     }
 
-    pub(crate) fn url_file_version(&self, url: &Url) -> Option<i32> {
+    pub(crate) fn url_file_version(&self, url: &Url) -> Option<i64> {
         let path = from_proto::vfs_path(&url).ok()?;
-        Some(self.mem_docs.get(&path)?.version)
+        self.mem_docs.get(&path)?.version
     }
 
     pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url {
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 93ac45415f..a5c65fa3e8 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -302,7 +302,7 @@ pub enum SnippetDocumentChangeOperation {
 #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
 pub struct SnippetTextDocumentEdit {
-    pub text_document: lsp_types::OptionalVersionedTextDocumentIdentifier,
+    pub text_document: lsp_types::VersionedTextDocumentIdentifier,
     pub edits: Vec<SnippetTextEdit>,
 }
 
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index 6427c73672..1d271a9d8b 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -51,7 +51,7 @@ impl GlobalState {
         }
         let percentage = fraction.map(|f| {
             assert!(0.0 <= f && f <= 1.0);
-            (f * 100.0) as u32
+            f * 100.0
         });
         let token = lsp_types::ProgressToken::String(format!("rustAnalyzer/{}", title));
         let work_done_progress = match state {
@@ -98,11 +98,11 @@ pub(crate) fn apply_document_changes(
     // The VFS will normalize the end of lines to `\n`.
     enum IndexValid {
         All,
-        UpToLineExclusive(u32),
+        UpToLineExclusive(u64),
     }
 
     impl IndexValid {
-        fn covers(&self, line: u32) -> bool {
+        fn covers(&self, line: u64) -> bool {
             match *self {
                 IndexValid::UpToLineExclusive(to) => to > line,
                 _ => true,
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 6ea08adcea..68a53bbcb9 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -368,7 +368,7 @@ impl GlobalState {
                 let url = file_id_to_url(&self.vfs.read().0, file_id);
                 let diagnostics = self.diagnostics.diagnostics_for(file_id).cloned().collect();
                 let version = from_proto::vfs_path(&url)
-                    .map(|path| self.mem_docs.get(&path).map(|it| it.version))
+                    .map(|path| self.mem_docs.get(&path)?.version)
                     .unwrap_or_default();
 
                 self.send_notification::<lsp_types::notification::PublishDiagnostics>(
@@ -521,7 +521,7 @@ impl GlobalState {
                 let mut version = None;
                 if let Ok(path) = from_proto::vfs_path(&params.text_document.uri) {
                     match this.mem_docs.remove(&path) {
-                        Some(doc) => version = Some(doc.version),
+                        Some(doc) => version = doc.version,
                         None => log::error!("orphan DidCloseTextDocument: {}", path),
                     }
 
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 2f35425bbc..4bdf4bf0fa 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -21,7 +21,9 @@ use crate::{
 
 pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
     let line_col = line_index.line_col(offset);
-    lsp_types::Position::new(line_col.line, line_col.col_utf16)
+    let line = u64::from(line_col.line);
+    let character = u64::from(line_col.col_utf16);
+    lsp_types::Position::new(line, character)
 }
 
 pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Range {
@@ -276,9 +278,9 @@ pub(crate) fn signature_help(
                     label.push_str(", ");
                 }
                 first = false;
-                let start = label.len() as u32;
+                let start = label.len() as u64;
                 label.push_str(param);
-                let end = label.len() as u32;
+                let end = label.len() as u64;
                 params.push(lsp_types::ParameterInformation {
                     label: lsp_types::ParameterLabel::LabelOffsets([start, end]),
                     documentation: None,
@@ -300,7 +302,7 @@ pub(crate) fn signature_help(
         })
     };
 
-    let active_parameter = call_info.active_parameter.map(|it| it as u32);
+    let active_parameter = call_info.active_parameter.map(|it| it as i64);
 
     let signature = lsp_types::SignatureInformation {
         label,
@@ -516,13 +518,13 @@ pub(crate) fn url_from_abs_path(path: &Path) -> lsp_types::Url {
     lsp_types::Url::parse(&url).unwrap()
 }
 
-pub(crate) fn optional_versioned_text_document_identifier(
+pub(crate) fn versioned_text_document_identifier(
     snap: &GlobalStateSnapshot,
     file_id: FileId,
-) -> lsp_types::OptionalVersionedTextDocumentIdentifier {
+) -> lsp_types::VersionedTextDocumentIdentifier {
     let url = url(snap, file_id);
     let version = snap.url_file_version(&url);
-    lsp_types::OptionalVersionedTextDocumentIdentifier { uri: url, version }
+    lsp_types::VersionedTextDocumentIdentifier { uri: url, version }
 }
 
 pub(crate) fn location(
@@ -611,7 +613,7 @@ pub(crate) fn snippet_text_document_edit(
     is_snippet: bool,
     source_file_edit: SourceFileEdit,
 ) -> Result<lsp_ext::SnippetTextDocumentEdit> {
-    let text_document = optional_versioned_text_document_identifier(snap, source_file_edit.file_id);
+    let text_document = versioned_text_document_identifier(snap, source_file_edit.file_id);
     let line_index = snap.analysis.file_line_index(source_file_edit.file_id)?;
     let line_endings = snap.file_line_endings(source_file_edit.file_id);
     let edits = source_file_edit
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 8c01db07c8..db9727bee4 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp_ext.rs hash: 203fdf79b21b5987
+lsp_ext.rs hash: 9d5daed5b25dc4f6
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this  issue:
@@ -45,7 +45,7 @@ interface SnippetTextEdit extends TextEdit {
 
 ```typescript
 export interface TextDocumentEdit {
-	textDocument: OptionalVersionedTextDocumentIdentifier;
+	textDocument: VersionedTextDocumentIdentifier;
 	edits: (TextEdit | SnippetTextEdit)[];
 }
 ```


Test patch:
diff --git a/crates/rust-analyzer/tests/rust-analyzer/support.rs b/crates/rust-analyzer/tests/rust-analyzer/support.rs
index 4561257893..b210b98f0d 100644
--- a/crates/rust-analyzer/tests/rust-analyzer/support.rs
+++ b/crates/rust-analyzer/tests/rust-analyzer/support.rs
@@ -108,7 +108,7 @@ pub(crate) fn project(fixture: &str) -> Server {
 }
 
 pub(crate) struct Server {
-    req_id: Cell<i32>,
+    req_id: Cell<u64>,
     messages: RefCell<Vec<Message>>,
     _thread: jod_thread::JoinHandle<()>,
     client: Connection,
@@ -165,7 +165,7 @@ impl Server {
         R::Params: Serialize,
     {
         let id = self.req_id.get();
-        self.req_id.set(id.wrapping_add(1));
+        self.req_id.set(id + 1);
 
         let r = Request::new(id.into(), R::METHOD.to_string(), params);
         self.send_request_(r)