about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <yuki.okushi@huawei.com>2021-10-17 04:51:22 +0900
committerYuki Okushi <yuki.okushi@huawei.com>2021-10-17 04:51:22 +0900
commitd4cc8774d598dd496a3dee393271c9c69a07e2fa (patch)
tree16d9fff74164eb1adabca2176861fbde9e50df0e
parent7fbd4ce2768744b3bd2ddf8453b73f4f18dbe5bc (diff)
downloadrust-d4cc8774d598dd496a3dee393271c9c69a07e2fa.tar.gz
rust-d4cc8774d598dd496a3dee393271c9c69a07e2fa.zip
Suggest a case insensitive match name regardless of levenshtein distance
-rw-r--r--compiler/rustc_span/src/lev_distance.rs36
-rw-r--r--compiler/rustc_span/src/lev_distance/tests.rs10
-rw-r--r--src/test/ui/hygiene/rustc-macro-transparency.stderr16
-rw-r--r--src/test/ui/issues/issue-22933-2.stderr5
4 files changed, 37 insertions, 30 deletions
diff --git a/compiler/rustc_span/src/lev_distance.rs b/compiler/rustc_span/src/lev_distance.rs
index cea7871923b..c10968e06d7 100644
--- a/compiler/rustc_span/src/lev_distance.rs
+++ b/compiler/rustc_span/src/lev_distance.rs
@@ -58,34 +58,28 @@ pub fn find_best_match_for_name(
     let lookup = &lookup.as_str();
     let max_dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
 
-    let (case_insensitive_match, levenshtein_match) = name_vec
+    // Priority of matches:
+    // 1. Exact case insensitive match
+    // 2. Levenshtein distance match
+    // 3. Sorted word match
+    if let Some(case_insensitive_match) =
+        name_vec.iter().find(|candidate| candidate.as_str().to_uppercase() == lookup.to_uppercase())
+    {
+        return Some(*case_insensitive_match);
+    }
+    let levenshtein_match = name_vec
         .iter()
         .filter_map(|&name| {
             let dist = lev_distance(lookup, &name.as_str());
             if dist <= max_dist { Some((name, dist)) } else { None }
         })
         // Here we are collecting the next structure:
-        // (case_insensitive_match, (levenshtein_match, levenshtein_distance))
-        .fold((None, None), |result, (candidate, dist)| {
-            (
-                if candidate.as_str().to_uppercase() == lookup.to_uppercase() {
-                    Some(candidate)
-                } else {
-                    result.0
-                },
-                match result.1 {
-                    None => Some((candidate, dist)),
-                    Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }),
-                },
-            )
+        // (levenshtein_match, levenshtein_distance)
+        .fold(None, |result, (candidate, dist)| match result {
+            None => Some((candidate, dist)),
+            Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }),
         });
-    // Priority of matches:
-    // 1. Exact case insensitive match
-    // 2. Levenshtein distance match
-    // 3. Sorted word match
-    if let Some(candidate) = case_insensitive_match {
-        Some(candidate)
-    } else if levenshtein_match.is_some() {
+    if levenshtein_match.is_some() {
         levenshtein_match.map(|(candidate, _)| candidate)
     } else {
         find_match_by_sorted_words(name_vec, lookup)
diff --git a/compiler/rustc_span/src/lev_distance/tests.rs b/compiler/rustc_span/src/lev_distance/tests.rs
index 11822e9ef97..b32f8d32c13 100644
--- a/compiler/rustc_span/src/lev_distance/tests.rs
+++ b/compiler/rustc_span/src/lev_distance/tests.rs
@@ -31,17 +31,13 @@ fn test_find_best_match_for_name() {
 
         assert_eq!(find_best_match_for_name(&input, Symbol::intern("1111111111"), None), None);
 
-        let input = vec![Symbol::intern("aAAA")];
+        let input = vec![Symbol::intern("AAAA")];
         assert_eq!(
-            find_best_match_for_name(&input, Symbol::intern("AAAA"), None),
-            Some(Symbol::intern("aAAA"))
+            find_best_match_for_name(&input, Symbol::intern("aaaa"), None),
+            Some(Symbol::intern("AAAA"))
         );
 
         let input = vec![Symbol::intern("AAAA")];
-        // Returns None because `lev_distance > max_dist / 3`
-        assert_eq!(find_best_match_for_name(&input, Symbol::intern("aaaa"), None), None);
-
-        let input = vec![Symbol::intern("AAAA")];
         assert_eq!(
             find_best_match_for_name(&input, Symbol::intern("aaaa"), Some(4)),
             Some(Symbol::intern("AAAA"))
diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr
index ef650b75b56..e4c1c8ad293 100644
--- a/src/test/ui/hygiene/rustc-macro-transparency.stderr
+++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr
@@ -2,11 +2,14 @@ error[E0425]: cannot find value `Opaque` in this scope
   --> $DIR/rustc-macro-transparency.rs:26:5
    |
 LL |     Opaque;
-   |     ^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `opaque`
+   |     ^^^^^^ not found in this scope
 
 error[E0423]: expected value, found macro `semitransparent`
   --> $DIR/rustc-macro-transparency.rs:29:5
    |
+LL |     struct SemiTransparent;
+   |     ----------------------- similarly named unit struct `SemiTransparent` defined here
+...
 LL |     semitransparent;
    |     ^^^^^^^^^^^^^^^ not a value
    |
@@ -14,10 +17,17 @@ help: use `!` to invoke the macro
    |
 LL |     semitransparent!;
    |                    +
+help: a unit struct with a similar name exists
+   |
+LL |     SemiTransparent;
+   |     ~~~~~~~~~~~~~~~
 
 error[E0423]: expected value, found macro `opaque`
   --> $DIR/rustc-macro-transparency.rs:30:5
    |
+LL |     struct Opaque;
+   |     -------------- similarly named unit struct `Opaque` defined here
+...
 LL |     opaque;
    |     ^^^^^^ not a value
    |
@@ -25,6 +35,10 @@ help: use `!` to invoke the macro
    |
 LL |     opaque!;
    |           +
+help: a unit struct with a similar name exists
+   |
+LL |     Opaque;
+   |     ~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-22933-2.stderr b/src/test/ui/issues/issue-22933-2.stderr
index 584b05ec44d..0bfbf538486 100644
--- a/src/test/ui/issues/issue-22933-2.stderr
+++ b/src/test/ui/issues/issue-22933-2.stderr
@@ -5,7 +5,10 @@ LL | enum Delicious {
    | -------------- variant or associated item `PIE` not found here
 ...
 LL |     ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
-   |                                                       ^^^ variant or associated item not found in `Delicious`
+   |                                                       ^^^
+   |                                                       |
+   |                                                       variant or associated item not found in `Delicious`
+   |                                                       help: there is a variant with a similar name: `Pie`
 
 error: aborting due to previous error