From 80c603fc6589aaf70df7c142723eef9a1d28aec5 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sat, 15 Jul 2017 10:26:11 -0700 Subject: [PATCH] path, not name, in sole-argument variant type mismatch suggestion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/librustc_typeck/check/demand.rs | 6 ++++-- src/test/ui/did_you_mean/issue-42764.rs | 2 +- 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 26d51178f4d7b..828106df7821b 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 285bd4b25665d..ecaeb7b1161f7 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 { FirstSome(T), AlternativeSome(T), - None, + Nothing, } fn this_function_expects_a_double_option(d: DoubleOption) {} diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr index 2d168cd4d01ac..7ba129039bc2f 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