Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3212,6 +3212,18 @@ impl<'a> Resolver<'a> {
let name = path[path.len() - 1].node.name;
// Make sure error reporting is deterministic.
names.sort_by_key(|name| name.as_str());


// Ugly code, just to see if using case insensitive comparison will help
let exact_match = names.iter().find(|x| x.as_str().to_uppercase() == name.as_str().to_uppercase());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case_insensitive_match would be a less-misleading name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the following to account for @petrochenkov's comment

names.iter().find(|x| {
    x.as_str().to_uppercase() == name.as_str().to_uppercase() && x.as_str() != name.as_str()
})

// do not use Levenstein, just return the value we found (if any)
if exact_match.is_some() {
return match exact_match {
Some(found) => Some(found.clone()),
_ => None,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Less nesting:

if case_insensitive_match.is_some() {
    return case_insensitive_match.cloned()
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can be written as

if let Some(found) = exact_match {
    return Some(found.clone());
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It occurs to me that we should likely be making this change as a "tiebreaker" in syntax::util::lev_distance::find_best_match_for_name itself: the only time case-insensitive match is going to do better than minimizing Levenshtein distance is when there's a tie for the minimum and the method makes an unlucky choice among the minima, as in the motivating example (TyInt and TyUint are both Levenshtein-distance 1 away from TyUInt).

match find_best_match_for_name(names.iter(), &name.as_str(), None) {
Some(found) if found != name => Some(found),
_ => None,
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/issue46332.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Original problem is Levenstein distance.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue-46332.rs (with the hyphen) as a file name would conform more with most of the other test file names. The license also needs to be at the top of the file (the build system will check).

fn TyUint() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(An enum variant rather than a function is closer to the spirit of the example in the issue (which isn't to say that we shouldn't test functions, too, but those are snake_case_in_standard_style, unlike TyUint).)

println!("TyUint");
}

fn TyInt() {
println!("TyInt");
}


fn main() {
TyUInt();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're missing the .stderr file in this PR.