diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-04-06 18:42:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-06 18:42:57 +0200 |
| commit | 3e21d6875f90eb0bc12833f73f56ec30cad6c1bd (patch) | |
| tree | 2a4ebb5c47989796e433cfc682e3f740a556226f | |
| parent | 0534655d9b5f61dbd75cf142ec8d2d3f68b550ee (diff) | |
| parent | 4fc3c6b07a5aff0bb3da87496daf825b128d6e08 (diff) | |
| download | rust-3e21d6875f90eb0bc12833f73f56ec30cad6c1bd.tar.gz rust-3e21d6875f90eb0bc12833f73f56ec30cad6c1bd.zip | |
Rollup merge of #109395 - chenyukang:yukang/fix-109291, r=cjgillot
Fix issue when there are multiple candidates for edit_distance_with_substrings Fixes #109291
| -rw-r--r-- | compiler/rustc_span/src/edit_distance.rs | 32 | ||||
| -rw-r--r-- | tests/ui/suggestions/issue-109291.rs | 4 | ||||
| -rw-r--r-- | tests/ui/suggestions/issue-109291.stderr | 12 |
3 files changed, 45 insertions, 3 deletions
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 89f0386e3e9..9fe9e3a7a5f 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -174,10 +174,10 @@ pub fn find_best_match_for_name( fn find_best_match_for_name_impl( use_substring_score: bool, candidates: &[Symbol], - lookup: Symbol, + lookup_symbol: Symbol, dist: Option<usize>, ) -> Option<Symbol> { - let lookup = lookup.as_str(); + let lookup = lookup_symbol.as_str(); let lookup_uppercase = lookup.to_uppercase(); // Priority of matches: @@ -190,6 +190,8 @@ fn find_best_match_for_name_impl( let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); let mut best = None; + // store the candidates with the same distance, only for `use_substring_score` current. + let mut next_candidates = vec![]; for c in candidates { match if use_substring_score { edit_distance_with_substrings(lookup, c.as_str(), dist) @@ -198,12 +200,36 @@ fn find_best_match_for_name_impl( } { Some(0) => return Some(*c), Some(d) => { - dist = d - 1; + if use_substring_score { + if d < dist { + dist = d; + next_candidates.clear(); + } else { + // `d == dist` here, we need to store the candidates with the same distance + // so we won't decrease the distance in the next loop. + } + next_candidates.push(*c); + } else { + dist = d - 1; + } best = Some(*c); } None => {} } } + + // We have a tie among several candidates, try to select the best among them ignoring substrings. + // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`, + // we select `force_capture` with a extra round of edit distance calculation. + if next_candidates.len() > 1 { + debug_assert!(use_substring_score); + best = find_best_match_for_name_impl( + false, + &next_candidates, + lookup_symbol, + Some(lookup.len()), + ); + } if best.is_some() { return best; } diff --git a/tests/ui/suggestions/issue-109291.rs b/tests/ui/suggestions/issue-109291.rs new file mode 100644 index 00000000000..1947b16a32e --- /dev/null +++ b/tests/ui/suggestions/issue-109291.rs @@ -0,0 +1,4 @@ +fn main() { + println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + //~^ ERROR no function or associated item name +} diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr new file mode 100644 index 00000000000..4ef5948d9bf --- /dev/null +++ b/tests/ui/suggestions/issue-109291.stderr @@ -0,0 +1,12 @@ +error[E0599]: no function or associated item named `forced_capture` found for struct `Backtrace` in the current scope + --> $DIR/issue-109291.rs:2:65 + | +LL | println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + | ^^^^^^^^^^^^^^ + | | + | function or associated item not found in `Backtrace` + | help: there is an associated function with a similar name: `force_capture` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. |
