Skip to content

Add case insensitive comparison, besides Levenstein for DYM #46347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 2, 2017
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
Member

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
Member

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
Member

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
Member

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
Member

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.