about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/lsp/utils.rs35
1 files changed, 12 insertions, 23 deletions
diff --git a/crates/rust-analyzer/src/lsp/utils.rs b/crates/rust-analyzer/src/lsp/utils.rs
index b388b317599..a4417e4d4a1 100644
--- a/crates/rust-analyzer/src/lsp/utils.rs
+++ b/crates/rust-analyzer/src/lsp/utils.rs
@@ -171,30 +171,19 @@ pub(crate) fn apply_document_changes(
     file_contents: impl FnOnce() -> String,
     mut content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
 ) -> String {
-    // Skip to the last full document change, as it invalidates all previous changes anyways.
-    let mut start = content_changes
-        .iter()
-        .rev()
-        .position(|change| change.range.is_none())
-        .map(|idx| content_changes.len() - idx - 1)
-        .unwrap_or(0);
-
-    let mut text: String = match content_changes.get_mut(start) {
-        // peek at the first content change as an optimization
-        Some(lsp_types::TextDocumentContentChangeEvent { range: None, text, .. }) => {
-            let text = mem::take(text);
-            start += 1;
-
-            // The only change is a full document update
-            if start == content_changes.len() {
-                return text;
+    // If at least one of the changes is a full document change, use the last
+    // of them as the starting point and ignore all previous changes.
+    let (mut text, content_changes) =
+        match content_changes.iter().rposition(|change| change.range.is_none()) {
+            Some(idx) => {
+                let text = mem::take(&mut content_changes[idx].text);
+                (text, &content_changes[idx + 1..])
             }
-            text
-        }
-        Some(_) => file_contents(),
-        // we received no content changes
-        None => return file_contents(),
-    };
+            None => (file_contents(), &content_changes[..]),
+        };
+    if content_changes.is_empty() {
+        return text;
+    }
 
     let mut line_index = LineIndex {
         // the index will be overwritten in the bottom loop's first iteration