Skip to content

Commit

Permalink
Rollup merge of #109395 - chenyukang:yukang/fix-109291, r=cjgillot
Browse files Browse the repository at this point in the history
Fix issue when there are multiple candidates for edit_distance_with_substrings

Fixes #109291
  • Loading branch information
matthiaskrgr committed Apr 6, 2023
2 parents 0534655 + 4fc3c6b commit 3e21d68
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
32 changes: 29 additions & 3 deletions compiler/rustc_span/src/edit_distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/suggestions/issue-109291.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture());
//~^ ERROR no function or associated item name
}
12 changes: 12 additions & 0 deletions tests/ui/suggestions/issue-109291.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 3e21d68

Please sign in to comment.