From 93d01eb443d0f871716c9d7faa3b69dc49662663 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Sun, 7 Jun 2015 17:56:18 -0700 Subject: [PATCH] Make the maximum edit distance of typo suggestions a function of the typo'd name's length. --- src/librustc_resolve/lib.rs | 16 ++++++++-------- src/test/compile-fail/bad-expr-path.rs | 4 ++-- src/test/compile-fail/bad-expr-path2.rs | 8 ++++---- src/test/compile-fail/typo-suggestion.rs | 21 +++++++++++++++++++++ 4 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 src/test/compile-fail/typo-suggestion.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cae0c7c7f5792..ba8680a35cb4b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3206,14 +3206,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { NoSuggestion } - fn find_best_match_for_name(&mut self, name: &str, max_distance: usize) - -> Option { - let this = &mut *self; - + fn find_best_match_for_name(&mut self, name: &str) -> Option { let mut maybes: Vec = Vec::new(); let mut values: Vec = Vec::new(); - for rib in this.value_ribs.iter().rev() { + for rib in self.value_ribs.iter().rev() { for (&k, _) in &rib.bindings { maybes.push(token::get_name(k)); values.push(usize::MAX); @@ -3229,9 +3226,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } + // As a loose rule to avoid obviously incorrect suggestions, clamp the + // maximum edit distance we will accept for a suggestion to one third of + // the typo'd name's length. + let max_distance = std::cmp::max(name.len(), 3) / 3; + if !values.is_empty() && - values[smallest] != usize::MAX && - values[smallest] < name.len() + 2 && values[smallest] <= max_distance && name != &maybes[smallest][..] { @@ -3357,7 +3357,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { NoSuggestion => { // limit search to 5 to reduce the number // of stupid suggestions - self.find_best_match_for_name(&path_name, 5) + self.find_best_match_for_name(&path_name) .map_or("".to_string(), |x| format!("`{}`", x)) } diff --git a/src/test/compile-fail/bad-expr-path.rs b/src/test/compile-fail/bad-expr-path.rs index 38ba652f53bc3..c35c9255ed28e 100644 --- a/src/test/compile-fail/bad-expr-path.rs +++ b/src/test/compile-fail/bad-expr-path.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `m1::a`. Did you mean `args`? +// error-pattern: unresolved name `m1::arguments`. Did you mean `arguments`? mod m1 {} -fn main(args: Vec) { log(debug, m1::a); } +fn main(arguments: Vec) { log(debug, m1::arguments); } diff --git a/src/test/compile-fail/bad-expr-path2.rs b/src/test/compile-fail/bad-expr-path2.rs index f397d0b387da5..af34887dec954 100644 --- a/src/test/compile-fail/bad-expr-path2.rs +++ b/src/test/compile-fail/bad-expr-path2.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: unresolved name `m1::a`. Did you mean `args`? +// error-pattern: unresolved name `m1::arguments`. Did you mean `arguments`? mod m1 { - pub mod a {} + pub mod arguments {} } -fn main(args: Vec) { - log(debug, m1::a); +fn main(arguments: Vec) { + log(debug, m1::arguments); } diff --git a/src/test/compile-fail/typo-suggestion.rs b/src/test/compile-fail/typo-suggestion.rs new file mode 100644 index 0000000000000..d5cf6a294ee4d --- /dev/null +++ b/src/test/compile-fail/typo-suggestion.rs @@ -0,0 +1,21 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let foo = 1; + + // `foo` shouldn't be suggested, it is too dissimilar from `bar`. + println!("Hello {}", bar); + //~^ ERROR: unresolved name `bar` + + // But this is close enough. + println!("Hello {}", fob); + //~^ ERROR: unresolved name `fob`. Did you mean `foo`? +}