diff options
| author | Zack M. Davis <code@zackmdavis.net> | 2017-07-15 10:26:11 -0700 |
|---|---|---|
| committer | Zack M. Davis <code@zackmdavis.net> | 2017-07-15 12:46:03 -0700 |
| commit | 80c603fc6589aaf70df7c142723eef9a1d28aec5 (patch) | |
| tree | c6e140a392247791f53cc08ca691d463e077707b | |
| parent | eac74104054ed1390f8c92be1d4163af128d38de (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/did_you_mean/issue-42764.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/did_you_mean/issue-42764.stderr | 8 |
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 |
