From 64ad3e2c423f701b856a6780380a0dbb03f90c22 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Fri, 23 Nov 2018 12:57:03 -0800 Subject: [PATCH] adjust enum type instead of variant suggestions for prelude enums The present author regrets not thinking of a more eloquent way to do this. --- src/librustc_resolve/lib.rs | 12 +++++++++- src/librustc_typeck/check/demand.rs | 1 + .../issue-56028-there-is-an-enum-variant.rs | 2 ++ src/test/ui/issues/issue-35675.stderr | 22 +++++++------------ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8f329283b1a28..e543677ef0621 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3237,7 +3237,17 @@ impl<'a> Resolver<'a> { err.span_suggestions_with_applicability( span, &msg, - enum_candidates.into_iter().map(|(_variant, enum_ty)| enum_ty), + enum_candidates.into_iter() + .map(|(_variant_path, enum_ty_path)| enum_ty_path) + // variants reƫxported in prelude doesn't mean `prelude::v1` is the + // type name! FIXME: is there a more principled way to do this that + // would work for other reƫxports? + .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1") + // also say `Option` rather than `std::prelude::v1::Option` + .map(|enum_ty_path| { + // FIXME #56861: DRYer prelude filtering + enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned() + }), Applicability::MachineApplicable, ); } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index db4b68611c51b..996b57f558cc5 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -123,6 +123,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let sole_field_ty = sole_field.ty(self.tcx, substs); if self.can_coerce(expr_ty, sole_field_ty) { let variant_path = self.tcx.item_path_str(variant.did); + // FIXME #56861: DRYer prelude filtering Some(variant_path.trim_start_matches("std::prelude::v1::").to_string()) } else { None diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs index ec41c41141616..264cfa449942c 100644 --- a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs +++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs @@ -7,6 +7,8 @@ enum Solidify { Set } enum UnorderedCollection { Set } fn setup() -> Set { Set } +//~^ ERROR cannot find type `Set` in this scope +//~| ERROR cannot find value `Set` in this scope fn main() { setup(); diff --git a/src/test/ui/issues/issue-35675.stderr b/src/test/ui/issues/issue-35675.stderr index 2f07ee7124d07..652e1695a85a6 100644 --- a/src/test/ui/issues/issue-35675.stderr +++ b/src/test/ui/issues/issue-35675.stderr @@ -41,13 +41,10 @@ error[E0573]: expected type, found variant `Ok` --> $DIR/issue-35675.rs:29:13 | LL | fn foo() -> Ok { - | ^^ not a type -help: try using the variant's enum - | -LL | fn foo() -> std::prelude::v1 { - | ^^^^^^^^^^^^^^^^ -LL | fn foo() -> std::result::Result { - | ^^^^^^^^^^^^^^^^^^^ + | ^^ + | | + | not a type + | help: try using the variant's enum: `std::result::Result` error[E0412]: cannot find type `Variant3` in this scope --> $DIR/issue-35675.rs:34:13 @@ -63,13 +60,10 @@ error[E0573]: expected type, found variant `Some` --> $DIR/issue-35675.rs:38:13 | LL | fn qux() -> Some { - | ^^^^ not a type -help: try using the variant's enum - | -LL | fn qux() -> std::prelude::v1::Option { - | ^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn qux() -> std::prelude::v1 { - | ^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | not a type + | help: try using the variant's enum: `Option` error: aborting due to 7 previous errors