field does not exist error: note fields if Levenshtein suggestion fails
When trying to access or initialize a nonexistent field, if we can't infer what
field was meant (by virtue of the purported field in the source being a small
Levenshtein distance away from an actual field, suggestive of a typo), issue a
note listing all the available fields. To reduce terminal clutter, we don't
issue the note when we have a `find_best_match_for_name` Levenshtein
suggestion: the suggestion is probably right.
The third argument of the call to `find_best_match_for_name` is changed to
`None`, accepting the default maximum Levenshtein distance of one-third of the
identifier supplied for correction. The previous value of `Some(name.len())`
was overzealous, inappropriately very Levenshtein-distant suggestions when the
attempted field access could not plausibly be a mere typo. For example, if a
struct has fields `mule` and `phone`, but I type `.donkey`, I'd rather the
error have a note listing that the available fields are, in fact, `mule` and
`phone` (which is the behavior induced by this patch) rather than the error
asking "did you mean `phone`?" (which is the behavior on master). The "only
find fits with at least one matching letter" comment was accurate when it was
first introduced in 09d992471 (January 2015), but is a vicious lie in its
present context before a call to `find_best_match_for_name` and must be
destroyed (replacing every letter is a Levenshtein distance of name.len()).
The present author claims that this suffices to resolve #42599.
This commit is contained in:
parent
6270257f4e
commit
bf7e91f61d
11 changed files with 114 additions and 13 deletions
|
|
@ -3,6 +3,8 @@ error[E0609]: no field `zz` on type `Foo`
|
|||
|
|
||||
17 | f.zz;
|
||||
| ^^ unknown field
|
||||
|
|
||||
= note: available fields are: bar
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2017 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod submodule {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Demo {
|
||||
pub favorite_integer: isize,
|
||||
secret_integer: isize,
|
||||
pub innocently_misspellable: ()
|
||||
}
|
||||
|
||||
impl Demo {
|
||||
fn new_with_secret_two() -> Self {
|
||||
Self { secret_integer: 2, inocently_mispellable: () }
|
||||
}
|
||||
|
||||
fn new_with_secret_three() -> Self {
|
||||
Self { secret_integer: 3, egregiously_nonexistent_field: () }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
use submodule::Demo;
|
||||
|
||||
let demo = Demo::default();
|
||||
let innocent_field_misaccess = demo.inocently_mispellable;
|
||||
// note shouldn't suggest private `secret_integer` field
|
||||
let egregious_field_misaccess = demo.egregiously_nonexistent_field;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
error[E0560]: struct `submodule::Demo` has no field named `inocently_mispellable`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:22:39
|
||||
|
|
||||
22 | Self { secret_integer: 2, inocently_mispellable: () }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ field does not exist - did you mean `innocently_misspellable`?
|
||||
|
||||
error[E0560]: struct `submodule::Demo` has no field named `egregiously_nonexistent_field`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:26:39
|
||||
|
|
||||
26 | Self { secret_integer: 3, egregiously_nonexistent_field: () }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `submodule::Demo` does not have this field
|
||||
|
|
||||
= note: available fields are: favorite_integer, secret_integer, innocently_misspellable
|
||||
|
||||
error[E0609]: no field `inocently_mispellable` on type `submodule::Demo`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:36:41
|
||||
|
|
||||
36 | let innocent_field_misaccess = demo.inocently_mispellable;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ did you mean `innocently_misspellable`?
|
||||
|
||||
error[E0609]: no field `egregiously_nonexistent_field` on type `submodule::Demo`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:38:42
|
||||
|
|
||||
38 | let egregious_field_misaccess = demo.egregiously_nonexistent_field;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown field
|
||||
|
|
||||
= note: available fields are: favorite_integer, innocently_misspellable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue