From cd290b427c4256e710a189c2d674bede00a30958 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Fri, 19 Nov 2021 12:46:03 +0100
Subject: [PATCH] fix: inlay param hint hiding heurstic is case unsensitive

---
 crates/ide/src/inlay_hints.rs | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index f3c5dce7c38..94af017d64b 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -441,15 +441,25 @@ fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) ->
         None => return false,
     };
 
+    // std is honestly too panic happy...
+    let str_split_at = |str: &str, at| str.is_char_boundary(at).then(|| argument.split_at(at));
+
     let param_name = param_name.trim_start_matches('_');
     let argument = argument.trim_start_matches('_');
-    if argument.strip_prefix(param_name).map_or(false, |s| s.starts_with('_')) {
-        return true;
+
+    match str_split_at(argument, param_name.len()) {
+        Some((prefix, rest)) if prefix.eq_ignore_ascii_case(param_name) => {
+            return rest.is_empty() || rest.starts_with('_');
+        }
+        _ => (),
     }
-    if argument.strip_suffix(param_name).map_or(false, |s| s.ends_with('_')) {
-        return true;
+    match argument.len().checked_sub(param_name.len()).and_then(|at| str_split_at(argument, at)) {
+        Some((rest, suffix)) if param_name.eq_ignore_ascii_case(suffix) => {
+            return rest.is_empty() || rest.ends_with('_');
+        }
+        _ => (),
     }
-    argument == param_name
+    false
 }
 
 /// Hide the parameter name of a unary function if it is a `_` - prefixed suffix of the function's name, or equal.
@@ -464,9 +474,13 @@ fn is_param_name_suffix_of_fn_name(
     match (callable.n_params(), fn_name) {
         (1, Some(function)) => {
             function == param_name
-                || (function.len() > param_name.len()
-                    && function.ends_with(param_name)
-                    && function[..function.len() - param_name.len()].ends_with('_'))
+                || function
+                    .len()
+                    .checked_sub(param_name.len())
+                    .and_then(|at| function.is_char_boundary(at).then(|| function.split_at(at)))
+                    .map_or(false, |(prefix, suffix)| {
+                        suffix.eq_ignore_ascii_case(param_name) && prefix.ends_with('_')
+                    })
         }
         _ => false,
     }
@@ -852,6 +866,9 @@ enum CompletionKind {
 fn non_ident_pat((a, b): (u32, u32)) {}
 
 fn main() {
+    const PARAM: u32 = 0;
+    foo(PARAM);
+
     check("");
 
     map(0);