Auto merge of #46461 - zackmdavis:elemental_method_suggestion_jamboree, r=estebank
type error method suggestions use whitelisted identity-like conversions  Previously, on a type mismatch (and if this wasn't preëmpted by a higher-priority suggestion), we would look for argumentless methods returning the expected type, and list them in a `help` note. This had two major shortcomings: firstly, a lot of the suggestions didn't really make sense (if you used a &str where a String was expected, `.to_ascii_uppercase()` is probably not the solution you were hoping for). Secondly, we weren't generating suggestions from the most useful traits! We address the first problem with an internal `#[rustc_conversion_suggestion]` attribute meant to mark methods that keep the "same value" in the relevant sense, just converting the type. We address the second problem by making `FnCtxt.probe_for_return_type` pass the `ProbeScope::AllTraits` to `probe_op`: this would seem to be safe because grep reveals no other callers of `probe_for_return_type`. Also, structured suggestions are pretty and good for RLS and friends. Unfortunately, the trait probing is still not all one would hope for: at a minimum, we don't know how to rule out `into()` in cases where it wouldn't actually work, and we don't know how to rule in `.to_owned()` where it would. Issues #46459 and #46460 have been filed and are ref'd in a FIXME. This is hoped to resolve #42929, #44672, and #45777.
This commit is contained in:
commit
6eff103aa1
14 changed files with 147 additions and 65 deletions
|
|
@ -2,16 +2,13 @@ error[E0308]: mismatched types
|
|||
--> $DIR/deref-suggestion.rs:18:9
|
||||
|
|
||||
18 | foo(s); //~ ERROR mismatched types
|
||||
| ^ expected struct `std::string::String`, found reference
|
||||
| ^
|
||||
| |
|
||||
| expected struct `std::string::String`, found reference
|
||||
| help: try using a conversion method: `s.to_string()`
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `&std::string::String`
|
||||
= help: here are some functions which might fulfill your needs:
|
||||
- .escape_debug()
|
||||
- .escape_default()
|
||||
- .escape_unicode()
|
||||
- .to_ascii_lowercase()
|
||||
- .to_ascii_uppercase()
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:23:10
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ error[E0055]: reached the recursion limit while auto-dereferencing I
|
|||
62 | let x: &Bottom = &t; //~ ERROR mismatched types
|
||||
| ^^ deref recursion limit reached
|
||||
|
|
||||
= help: consider adding a `#[recursion_limit="20"]` attribute to your crate
|
||||
= help: consider adding a `#![recursion_limit="20"]` attribute to your crate
|
||||
|
||||
error[E0055]: reached the recursion limit while auto-dereferencing I
|
||||
|
|
||||
= help: consider adding a `#[recursion_limit="20"]` attribute to your crate
|
||||
= help: consider adding a `#![recursion_limit="20"]` attribute to your crate
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recursion_limit_deref.rs:62:22
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ error[E0308]: mismatched types
|
|||
|
|
||||
= note: expected type `usize`
|
||||
found type `std::string::String`
|
||||
= help: here are some functions which might fulfill your needs:
|
||||
- .capacity()
|
||||
- .len()
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coerce-suggestions.rs:19:19
|
||||
|
|
@ -44,7 +41,10 @@ error[E0308]: mismatched types
|
|||
--> $DIR/coerce-suggestions.rs:27:9
|
||||
|
|
||||
27 | f = box f;
|
||||
| ^^^^^ cyclic type of infinite size
|
||||
| ^^^^^
|
||||
| |
|
||||
| cyclic type of infinite size
|
||||
| help: try using a conversion method: `box f.to_string()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coerce-suggestions.rs:31:9
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ error[E0308]: mismatched types
|
|||
|
|
||||
= note: expected type `usize`
|
||||
found type `&'static str`
|
||||
= help: here are some functions which might fulfill your needs:
|
||||
- .len()
|
||||
|
||||
error[E0061]: this function takes 2 parameters but 3 parameters were supplied
|
||||
--> $DIR/issue-34264.rs:20:5
|
||||
|
|
|
|||
23
src/test/ui/suggestions/conversion-methods.rs
Normal file
23
src/test/ui/suggestions/conversion-methods.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// 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.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
|
||||
fn main() {
|
||||
let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
|
||||
let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
|
||||
}
|
||||
50
src/test/ui/suggestions/conversion-methods.stderr
Normal file
50
src/test/ui/suggestions/conversion-methods.stderr
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/conversion-methods.rs:15:41
|
||||
|
|
||||
15 | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected struct `std::string::String`, found reference
|
||||
| help: try using a conversion method: `"'Tis a fond Ambush—".to_string()`
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/conversion-methods.rs:16:40
|
||||
|
|
||||
16 | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected struct `std::path::PathBuf`, found reference
|
||||
| help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
|
||||
|
|
||||
= note: expected type `std::path::PathBuf`
|
||||
found type `&std::path::Path`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/conversion-methods.rs:19:40
|
||||
|
|
||||
19 | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
|
||||
| ^
|
||||
| |
|
||||
| expected struct `std::string::String`, found integral variable
|
||||
| help: try using a conversion method: `2.to_string()`
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/conversion-methods.rs:22:47
|
||||
|
|
||||
22 | let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
|
||||
| ^^^^^^^^^^
|
||||
| |
|
||||
| expected struct `std::vec::Vec`, found reference
|
||||
| help: try using a conversion method: `&[1, 2, 3].to_vec()`
|
||||
|
|
||||
= note: expected type `std::vec::Vec<usize>`
|
||||
found type `&[{integer}; 3]`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue