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.
This commit is contained in:
Zack M. Davis 2017-07-15 10:26:11 -07:00
parent eac7410405
commit 80c603fc65
3 changed files with 9 additions and 7 deletions

View File

@ -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);
}
}

View File

@ -11,7 +11,7 @@
enum DoubleOption<T> {
FirstSome(T),
AlternativeSome(T),
None,
Nothing,
}
fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {}

View File

@ -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