diff options
| author | Zack M. Davis <code@zackmdavis.net> | 2017-11-19 11:25:35 -0800 |
|---|---|---|
| committer | Zack M. Davis <code@zackmdavis.net> | 2018-01-06 17:15:59 -0800 |
| commit | aba56ddd05d821b6f0a3e5fc05bc47311e09051c (patch) | |
| tree | c9c40e980387f5a32cc611e82e4da0df602d7ba7 /src/test | |
| parent | 72176cf96cb79a0ebf62972b76dbe68c933bef4d (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.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/did_you_mean/recursion_limit_deref.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/span/coerce-suggestions.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/span/issue-34264.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/suggestions/conversion-methods.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/suggestions/conversion-methods.stderr | 50 |
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 + |
