-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Targeted suggestions for specific "no method" errors on standard library types #59450
Comments
Do you think this would be a common enough pattern that it'd be worth creating something like Something like
|
Something similar to rustc_on_unimplemented sounds like it would work! I don't know enough about the diagnostics implementation to know what the other options are. Bonus points if it is straightforward for a new rustc contributor to add a confusable and corresponding test case. |
We could also reuse (abuse?) |
Maybe relevant: #107108 adds |
…ons, r=cjgillot Add `#[rustc_confusables]` attribute to allow targeted "no method" error suggestions on standard library types After this PR, the standard library developer can annotate methods on e.g. `BTreeSet::push` with `#[rustc_confusables("insert")]`. When the user mistypes `btreeset.push()`, `BTreeSet::insert` will be suggested if there are no other candidates to suggest. This PR lays the foundations for contributors to add `rustc_confusables` annotations to standard library types for targeted suggestions, as specified in rust-lang#59450, or to address cases such as rust-lang#108437. ### Example Assume `BTreeSet` is the standard library type: ``` // Standard library definition #![feature(rustc_attrs)] struct BTreeSet; impl BTreeSet { #[rustc_confusables("push")] fn insert(&self) {} } // User code fn main() { let x = BTreeSet {}; x.push(); } ``` A new suggestion (which has lower precedence than suggestions for misspellings and only is shown when there are no misspellings suggestions) will be added to hint the user maybe they intended to write `x.insert()` instead: ``` error[E0599]: no method named `push` found for struct `BTreeSet` in the current scope --> test.rs:12:7 | 3 | struct BTreeSet; | --------------- method `push` not found for this struct ... 12 | x.push(); | ^^^^ method not found in `BTreeSet` | help: you might have meant to use `insert` | 12 | x.insert(); | ~~~~~~ error: aborting due to previous error ```
Now that PR #112239 is merged, it should be easy to add |
Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` rust-lang#59450
Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` rust-lang#59450
Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` rust-lang#59450
Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` rust-lang#59450
I'll have #120730 close this ticket. We can open new ones for specific methods that require more aliases. |
Provide suggestions through `rustc_confusables` annotations Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` Fix rust-lang#59450 (we can open subsequent tickets for specific cases). Fix rust-lang#108437: ``` error[E0599]: `Option<{integer}>` is not an iterator --> f101.rs:3:9 | 3 | opt.flat_map(|val| Some(val)); | ^^^^^^^^ `Option<{integer}>` is not an iterator | ::: /home/gh-estebank/rust/library/core/src/option.rs:571:1 | 571 | pub enum Option<T> { | ------------------ doesn't satisfy `Option<{integer}>: Iterator` | = note: the following trait bounds were not satisfied: `Option<{integer}>: Iterator` which is required by `&mut Option<{integer}>: Iterator` help: you might have meant to use `and_then` | 3 | opt.and_then(|val| Some(val)); | ~~~~~~~~ ``` On type error of method call arguments, look at confusables for suggestion. Fix rust-lang#87212: ``` error[E0308]: mismatched types --> f101.rs:8:18 | 8 | stuff.append(Thing); | ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing` | | | arguments to this method are incorrect | = note: expected mutable reference `&mut Vec<Thing>` found struct `Thing` note: method defined here --> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12 | 2025 | pub fn append(&mut self, other: &mut Self) { | ^^^^^^ help: you might have meant to use `push` | 8 | stuff.push(Thing); | ~~~~ ```
Provide suggestions through `rustc_confusables` annotations Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` Fix rust-lang#59450 (we can open subsequent tickets for specific cases). Fix rust-lang#108437: ``` error[E0599]: `Option<{integer}>` is not an iterator --> f101.rs:3:9 | 3 | opt.flat_map(|val| Some(val)); | ^^^^^^^^ `Option<{integer}>` is not an iterator | ::: /home/gh-estebank/rust/library/core/src/option.rs:571:1 | 571 | pub enum Option<T> { | ------------------ doesn't satisfy `Option<{integer}>: Iterator` | = note: the following trait bounds were not satisfied: `Option<{integer}>: Iterator` which is required by `&mut Option<{integer}>: Iterator` help: you might have meant to use `and_then` | 3 | opt.and_then(|val| Some(val)); | ~~~~~~~~ ``` On type error of method call arguments, look at confusables for suggestion. Fix rust-lang#87212: ``` error[E0308]: mismatched types --> f101.rs:8:18 | 8 | stuff.append(Thing); | ------ ^^^^^ expected `&mut Vec<Thing>`, found `Thing` | | | arguments to this method are incorrect | = note: expected mutable reference `&mut Vec<Thing>` found struct `Thing` note: method defined here --> /home/gh-estebank/rust/library/alloc/src/vec/mod.rs:2025:12 | 2025 | pub fn append(&mut self, other: &mut Self) { | ^^^^^^ help: you might have meant to use `push` | 8 | stuff.push(Thing); | ~~~~ ```
Help with common API confusion, like asking for `push` when the data structure really has `append`. ``` error[E0599]: no method named `size` found for struct `Vec<{integer}>` in the current scope --> $DIR/rustc_confusables_std_cases.rs:17:7 | LL | x.size(); | ^^^^ | help: you might have meant to use `len` | LL | x.len(); | ~~~ help: there is a method with a similar name | LL | x.resize(); | ~~~~~~ ``` rust-lang#59450
Rustc currently shows a perfectly reasonable error message when calling a nonexistent method:
But for specific frequently encountered cases, it would be great to show a more targeted error that gives the name of the method you almost definitely meant to call, despite not being similar enough to trigger the "did you mean" suggestion.
Candidates would be cases that arise often from refactoring (this applies to BTreeSet::push, which I see every now and then after replacing a Vec with a BTreeSet) or cases of a Rust API being named differently from an equivalent C++ API.
insert
push
push_back
len
The text was updated successfully, but these errors were encountered: