about summary refs log tree commit diff
path: root/compiler/rustc_span/src
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2024-01-11 00:24:46 +0800
committeryukang <moorekang@gmail.com>2024-01-12 18:50:36 +0800
commitca421fe1d3cba0dbd1b0dcc52c3d040fce63971a (patch)
treed683810ebd784e4a2e576adf7b32bb2f25d6ff65 /compiler/rustc_span/src
parente9271846294c4ee5bd7706df68180320c0b5ff20 (diff)
downloadrust-ca421fe1d3cba0dbd1b0dcc52c3d040fce63971a.tar.gz
rust-ca421fe1d3cba0dbd1b0dcc52c3d040fce63971a.zip
check rust lints when an unknown lint is detected
Diffstat (limited to 'compiler/rustc_span/src')
-rw-r--r--compiler/rustc_span/src/edit_distance.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 14cb1d6d362..87a0ccbb1a5 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -170,6 +170,34 @@ pub fn find_best_match_for_name(
     find_best_match_for_name_impl(false, candidates, lookup, dist)
 }
 
+/// Find the best match for multiple words
+///
+/// This function is intended for use when the desired match would never be
+/// returned due to a substring in `lookup` which is superfluous.
+///
+/// For example, when looking for the closest lint name to `clippy:missing_docs`,
+/// we would find `clippy::erasing_op`, despite `missing_docs` existing and being a better suggestion.
+/// `missing_docs` would have a larger edit distance because it does not contain the `clippy` tool prefix.
+/// In order to find `missing_docs`, this function takes multiple lookup strings, computes the best match
+/// for each and returns the match which had the lowest edit distance. In our example, `clippy:missing_docs` and
+/// `missing_docs` would be `lookups`, enabling `missing_docs` to be the best match, as desired.
+pub fn find_best_match_for_names(
+    candidates: &[Symbol],
+    lookups: &[Symbol],
+    dist: Option<usize>,
+) -> Option<Symbol> {
+    lookups
+        .iter()
+        .map(|s| (s, find_best_match_for_name_impl(false, candidates, *s, dist)))
+        .filter_map(|(s, r)| r.map(|r| (s, r)))
+        .min_by(|(s1, r1), (s2, r2)| {
+            let d1 = edit_distance(s1.as_str(), r1.as_str(), usize::MAX).unwrap();
+            let d2 = edit_distance(s2.as_str(), r2.as_str(), usize::MAX).unwrap();
+            d1.cmp(&d2)
+        })
+        .map(|(_, r)| r)
+}
+
 #[cold]
 fn find_best_match_for_name_impl(
     use_substring_score: bool,