about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShoyu Vanilla (Flint) <modulo641@gmail.com>2025-09-20 13:32:39 +0000
committerGitHub <noreply@github.com>2025-09-20 13:32:39 +0000
commitc8182c4ae3f40b77e12db4980433ca1a9a1b59a1 (patch)
tree9831bea2714157e64a6cf6e47f0228085b7a620b
parent3810e1732be762d851d9d3a1d2fca132d4b0aff5 (diff)
parentc38c6b862851b6ff1a897037e1cb16898cfbf44f (diff)
downloadrust-c8182c4ae3f40b77e12db4980433ca1a9a1b59a1.tar.gz
rust-c8182c4ae3f40b77e12db4980433ca1a9a1b59a1.zip
Merge pull request #20706 from A4-Tacks/stdx-replace-inplace
Fix to implements in-place stdx::replace
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/lib.rs44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
index 978c50d807b..5fa00741637 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
@@ -187,11 +187,19 @@ pub fn is_upper_snake_case(s: &str) -> bool {
 }
 
 pub fn replace(buf: &mut String, from: char, to: &str) {
-    if !buf.contains(from) {
+    let replace_count = buf.chars().filter(|&ch| ch == from).count();
+    if replace_count == 0 {
         return;
     }
-    // FIXME: do this in place.
-    *buf = buf.replace(from, to);
+    let from_len = from.len_utf8();
+    let additional = to.len().saturating_sub(from_len);
+    buf.reserve(additional * replace_count);
+
+    let mut end = buf.len();
+    while let Some(i) = buf[..end].rfind(from) {
+        buf.replace_range(i..i + from_len, to);
+        end = i;
+    }
 }
 
 #[must_use]
@@ -343,4 +351,34 @@ mod tests {
             "fn main() {\n    return 92;\n}\n"
         );
     }
+
+    #[test]
+    fn test_replace() {
+        #[track_caller]
+        fn test_replace(src: &str, from: char, to: &str, expected: &str) {
+            let mut s = src.to_owned();
+            replace(&mut s, from, to);
+            assert_eq!(s, expected, "from: {from:?}, to: {to:?}");
+        }
+
+        test_replace("", 'a', "b", "");
+        test_replace("", 'a', "😀", "");
+        test_replace("", '😀', "a", "");
+        test_replace("a", 'a', "b", "b");
+        test_replace("aa", 'a', "b", "bb");
+        test_replace("ada", 'a', "b", "bdb");
+        test_replace("a", 'a', "😀", "😀");
+        test_replace("😀", '😀', "a", "a");
+        test_replace("😀x", '😀', "a", "ax");
+        test_replace("y😀x", '😀', "a", "yax");
+        test_replace("a,b,c", ',', ".", "a.b.c");
+        test_replace("a,b,c", ',', "..", "a..b..c");
+        test_replace("a.b.c", '.', "..", "a..b..c");
+        test_replace("a.b.c", '.', "..", "a..b..c");
+        test_replace("a😀b😀c", '😀', ".", "a.b.c");
+        test_replace("a.b.c", '.', "😀", "a😀b😀c");
+        test_replace("a.b.c", '.', "😀😀", "a😀😀b😀😀c");
+        test_replace(".a.b.c.", '.', "()", "()a()b()c()");
+        test_replace(".a.b.c.", '.', "", "abc");
+    }
 }