@@ -4816,6 +4816,75 @@ pub impl Resolver {
4816
4816
}
4817
4817
}
4818
4818
4819
+ fn find_best_match_for_name(@mut self, name: &str) -> Option<~str> {
4820
+ let mut maybes: ~[~str] = ~[];
4821
+ let mut values: ~[uint] = ~[];
4822
+
4823
+ let mut j = self.value_ribs.len();
4824
+ while j != 0 {
4825
+ j -= 1;
4826
+ let rib = self.value_ribs.get_elt(j);
4827
+ for rib.bindings.each_entry |e| {
4828
+ vec::push(&mut maybes, copy *self.session.str_of(e.key));
4829
+ vec::push(&mut values, uint::max_value);
4830
+ }
4831
+ }
4832
+
4833
+ // Levenshtein Distance between two strings
4834
+ fn distance(s: &str, t: &str) -> uint {
4835
+
4836
+ let slen = str::len(s);
4837
+ let tlen = str::len(t);
4838
+
4839
+ if slen == 0 { return tlen; }
4840
+ if tlen == 0 { return slen; }
4841
+
4842
+ let mut dcol = vec::from_fn(tlen + 1, |x| x);
4843
+
4844
+ for str::each_chari(s) |i, sc| {
4845
+
4846
+ let mut current = i;
4847
+ dcol[0] = current + 1;
4848
+
4849
+ for str::each_chari(t) |j, tc| {
4850
+
4851
+ let mut next = dcol[j + 1];
4852
+
4853
+ if sc == tc {
4854
+ dcol[j + 1] = current;
4855
+ } else {
4856
+ dcol[j + 1] = cmp::min(current, next);
4857
+ dcol[j + 1] = cmp::min(dcol[j + 1], dcol[j]) + 1;
4858
+ }
4859
+
4860
+ current = next;
4861
+ }
4862
+ }
4863
+
4864
+ return dcol[tlen];
4865
+ }
4866
+
4867
+ let mut smallest = 0;
4868
+ for vec::eachi(maybes) |i, &other| {
4869
+
4870
+ values[i] = distance(name, other);
4871
+
4872
+ if values[i] <= values[smallest] {
4873
+ smallest = i;
4874
+ }
4875
+ }
4876
+
4877
+ if vec::len(values) > 0 &&
4878
+ values[smallest] != uint::max_value &&
4879
+ values[smallest] < str::len(name) + 2 {
4880
+
4881
+ Some(vec::swap_remove(&mut maybes, smallest))
4882
+
4883
+ } else {
4884
+ None
4885
+ }
4886
+ }
4887
+
4819
4888
fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
4820
4889
let mut i = self.type_ribs.len();
4821
4890
while i != 0 {
@@ -4882,9 +4951,20 @@ pub impl Resolver {
4882
4951
wrong_name) ) ;
4883
4952
}
4884
4953
else {
4885
- self . session. span_err( expr. span,
4886
- fmt!( "unresolved name: %s",
4954
+ match self . find_best_match_for_name( wrong_name) {
4955
+
4956
+ Some ( m) => {
4957
+ self . session. span_err( expr. span,
4958
+ fmt!( "unresolved name: `%s`. \
4959
+ Did you mean: `%s`?",
4960
+ wrong_name, m) ) ;
4961
+ }
4962
+ None => {
4963
+ self . session. span_err( expr. span,
4964
+ fmt!( "unresolved name: `%s`. ",
4887
4965
wrong_name) ) ;
4966
+ }
4967
+ }
4888
4968
}
4889
4969
}
4890
4970
}
0 commit comments