about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZack M. Davis <code@zackmdavis.net>2017-07-15 10:26:11 -0700
committerZack M. Davis <code@zackmdavis.net>2017-07-15 12:46:03 -0700
commit80c603fc6589aaf70df7c142723eef9a1d28aec5 (patch)
treec6e140a392247791f53cc08ca691d463e077707b
parenteac74104054ed1390f8c92be1d4163af128d38de (diff)
downloadrust-80c603fc6589aaf70df7c142723eef9a1d28aec5.tar.gz
rust-80c603fc6589aaf70df7c142723eef9a1d28aec5.zip
path, not name, in sole-argument variant type mismatch suggestion
We want the suggested replacement (which IDE tooling and such might offer to
automatically swap in) to, like, actually be correct: suggesting `MyVariant(x)`
when the actual fix is `MyEnum::MyVariant(x)` might be better than nothing, but
Rust is supposed to be the future of computing: we're better than better than
nothing.

As an exceptional case, we excise the prelude path, preferring to suggest
`Some` or `Ok` rather than `std::prelude::v1::Some` and
`std::prelude::v2::Ok`. (It's not worth the effort to future-proof against
hypothetical preludes v2, v3, &c.: we trust our successors to grep—excuse me,
ripgrep—for that.)

Also, don't make this preëmpt the existing probe-for-return-type suggestions,
despite their being looked unfavorably upon, at least in this situation
(https://github.com/rust-lang/rust/issues/42764#issuecomment-311388958): Cody
Schafer pointed out that that's a separate issue
(https://github.com/rust-lang/rust/pull/43178#issuecomment-314953229).

This is in the matter of #42764.
-rw-r--r--src/librustc_typeck/check/demand.rs6
-rw-r--r--src/test/ui/did_you_mean/issue-42764.rs2
-rw-r--r--src/test/ui/did_you_mean/issue-42764.stderr8
3 files changed, 9 insertions, 7 deletions
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 26d51178f4d..828106df782 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -106,7 +106,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         let sole_field = &variant.fields[0];
                         let sole_field_ty = sole_field.ty(self.tcx, substs);
                         if self.can_coerce(expr_ty, sole_field_ty) {
-                            compatible_variants.push(variant.name);
+                            let mut variant_path = self.tcx.item_path_str(variant.did);
+                            variant_path = variant_path.trim_left_matches("std::prelude::v1::")
+                                .to_string();
+                            compatible_variants.push(variant_path);
                         }
                     }
                 }
@@ -117,7 +120,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     err.span_suggestions(expr.span,
                                          "perhaps you meant to use a variant of the expected type",
                                          suggestions);
-                    return Some(err);
                 }
             }
 
diff --git a/src/test/ui/did_you_mean/issue-42764.rs b/src/test/ui/did_you_mean/issue-42764.rs
index 285bd4b2566..ecaeb7b1161 100644
--- a/src/test/ui/did_you_mean/issue-42764.rs
+++ b/src/test/ui/did_you_mean/issue-42764.rs
@@ -11,7 +11,7 @@
 enum DoubleOption<T> {
     FirstSome(T),
     AlternativeSome(T),
-    None,
+    Nothing,
 }
 
 fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {}
diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr
index 2d168cd4d01..7ba129039bc 100644
--- a/src/test/ui/did_you_mean/issue-42764.stderr
+++ b/src/test/ui/did_you_mean/issue-42764.stderr
@@ -8,10 +8,10 @@ error[E0308]: mismatched types
               found type `usize`
 help: perhaps you meant to use a variant of the expected type
    |
-21 |     this_function_expects_a_double_option(FirstSome(n));
-   |                                           ^^^^^^^^^^^^
-21 |     this_function_expects_a_double_option(AlternativeSome(n));
-   |                                           ^^^^^^^^^^^^^^^^^^
+21 |     this_function_expects_a_double_option(DoubleOption::FirstSome(n));
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
+21 |     this_function_expects_a_double_option(DoubleOption::AlternativeSome(n));
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error