about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-10 09:34:24 +0000
committerGitHub <noreply@github.com>2021-01-10 09:34:24 +0000
commit4fddf40f5bd51066e3201f319f7a5c1466483b4d (patch)
tree7aeb7cfd43b5a25f7e06a4e8c1df7cd6eb177f60
parentd0c2456994848479331c3434631996668039fc3a (diff)
parent5e81892d4dd3b8353d11df8b9239432b5aa10512 (diff)
downloadrust-4fddf40f5bd51066e3201f319f7a5c1466483b4d.tar.gz
rust-4fddf40f5bd51066e3201f319f7a5c1466483b4d.zip
Merge #7224
7224: Remove unnecessary allocation when checking whether to hide argument name hint r=jhpratt a=jhpratt

The case-insensitive prefix/suffix check can be performed
character-by-character. This allows the check to be done without having
to allocate a new string. As a side effect, it's also no longer
necessary to convert the entire string to lowercase, as it's done as
needed. As the only case equality we're handling is ASCII, this
operation can be further optimized by using byte equality, rather than
character equality.

cc @SomeoneToIgnore, as it's an update on my PR from yesterday.

Co-authored-by: Jacob Pratt <jacob@jhpratt.dev>
-rw-r--r--crates/ide/src/inlay_hints.rs26
1 files changed, 19 insertions, 7 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index a74829cd0d8..3e9a65d9c72 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -353,13 +353,25 @@ fn is_argument_similar_to_param_name(
     }
     match get_string_representation(argument) {
         None => false,
-        Some(mut repr) => {
-            let param_name = param_name.to_ascii_lowercase();
-            let argument_string = {
-                repr.make_ascii_lowercase();
-                repr.trim_start_matches('_')
-            };
-            argument_string.starts_with(&param_name) || argument_string.ends_with(&param_name)
+        Some(argument_string) => {
+            let num_leading_underscores =
+                argument_string.bytes().take_while(|&c| c == b'_').count();
+
+            // Does the argument name begin with the parameter name? Ignore leading underscores.
+            let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores);
+            let starts_with_pattern = param_name.bytes().all(
+                |expected| matches!(arg_bytes.next(), Some(actual) if expected.eq_ignore_ascii_case(&actual)),
+            );
+
+            if starts_with_pattern {
+                return true;
+            }
+
+            // Does the argument name end with the parameter name?
+            let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores);
+            param_name.bytes().rev().all(
+                |expected| matches!(arg_bytes.next_back(), Some(actual) if expected.eq_ignore_ascii_case(&actual)),
+            )
         }
     }
 }