about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorZack M. Davis <code@zackmdavis.net>2017-11-19 11:25:35 -0800
committerZack M. Davis <code@zackmdavis.net>2018-01-06 17:15:59 -0800
commitaba56ddd05d821b6f0a3e5fc05bc47311e09051c (patch)
treec9c40e980387f5a32cc611e82e4da0df602d7ba7 /src/test
parent72176cf96cb79a0ebf62972b76dbe68c933bef4d (diff)
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 preferred (because they're pretty, but
also for RLS and friends).

Also also, we make the E0055 autoderef recursion limit error use the
one-time-diagnostics set, because we can potentially hit the limit a lot
during probing. (Without this,
test/ui/did_you_mean/recursion_limit_deref.rs would report "aborting due to
51 errors").

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.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/deref-suggestion.stderr11
-rw-r--r--src/test/ui/did_you_mean/recursion_limit_deref.stderr4
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr8
-rw-r--r--src/test/ui/span/issue-34264.stderr2
-rw-r--r--src/test/ui/suggestions/conversion-methods.rs23
-rw-r--r--src/test/ui/suggestions/conversion-methods.stderr50
6 files changed, 83 insertions, 15 deletions
diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr
index 98ec3d9693f..4c2896e2207 100644
--- a/src/test/ui/deref-suggestion.stderr
+++ b/src/test/ui/deref-suggestion.stderr
@@ -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
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
index 951b0b10580..860c6bb5b90 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -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
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 07852619765..06f0e6ec228 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -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
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 3794d6ba2de..18860a7456e 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -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
diff --git a/src/test/ui/suggestions/conversion-methods.rs b/src/test/ui/suggestions/conversion-methods.rs
new file mode 100644
index 00000000000..8a53bc3ca93
--- /dev/null
+++ b/src/test/ui/suggestions/conversion-methods.rs
@@ -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
+}
diff --git a/src/test/ui/suggestions/conversion-methods.stderr b/src/test/ui/suggestions/conversion-methods.stderr
new file mode 100644
index 00000000000..96fdc29d952
--- /dev/null
+++ b/src/test/ui/suggestions/conversion-methods.stderr
@@ -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
+