Skip to content

Commit b0d3d3b

Browse files
committedOct 21, 2018
only issue "variant of the expected type" suggestion for enums
Felix S. Klock II pointed out that this suggestion (introduced in pull-request #43178 / eac7410) was being issued for one-field-struct expected types (in which case it is misleading and outright wrong), even though it was only intended for one-field enum-variants (most notably, `Some`). Particularly tender-hearted code-historians may be inclined to show mercy towards the author of #43178 on the grounds that it's somewhat confusing that struct field definitions are given in a type called `ty::VariantDef`. Add a conditional to adhere to the original intent. (It would be possible to generalize to structs, but not obviously net desirable.) This adds a level of indentation, so the diff here is going to be easier to read in ignore-whitespace mode (`-w`). Resolves #55250.
1 parent 22cc2ae commit b0d3d3b

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed
 

‎src/librustc_typeck/check/demand.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
111111
let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
112112
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
113113

114-
// If the expected type is an enum with any variants whose sole
115-
// field is of the found type, suggest such variants. See Issue
116-
// #42764.
114+
// If the expected type is an enum (Issue #55250) with any variants whose
115+
// sole field is of the found type, suggest such variants. (Issue #42764)
117116
if let ty::Adt(expected_adt, substs) = expected.sty {
117+
if expected_adt.is_enum() {
118118
let mut compatible_variants = expected_adt.variants
119119
.iter()
120120
.filter(|variant| variant.fields.len() == 1)
@@ -131,8 +131,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
131131

132132
if compatible_variants.peek().is_some() {
133133
let expr_text = print::to_string(print::NO_ANN, |s| s.print_expr(expr));
134-
let suggestions = compatible_variants.map(|v|
135-
format!("{}({})", v, expr_text)).collect::<Vec<_>>();
134+
let suggestions = compatible_variants
135+
.map(|v| format!("{}({})", v, expr_text)).collect::<Vec<_>>();
136136
err.span_suggestions_with_applicability(
137137
expr.span,
138138
"try using a variant of the expected type",
@@ -141,6 +141,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
141141
);
142142
}
143143
}
144+
}
144145

145146
self.suggest_ref_or_into(&mut err, expr, expected, expr_ty);
146147

‎src/test/ui/did_you_mean/issue-42764.rs

+16
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,20 @@ fn main() {
2020
let n: usize = 42;
2121
this_function_expects_a_double_option(n);
2222
//~^ ERROR mismatched types
23+
//~| HELP try using a variant of the expected type
24+
}
25+
26+
27+
// But don't issue the "try using a variant" help if the one-"variant" ADT is
28+
// actually a one-field struct.
29+
30+
struct Payload;
31+
32+
struct Wrapper { payload: Payload }
33+
34+
struct Context { wrapper: Wrapper }
35+
36+
fn overton() {
37+
let _c = Context { wrapper: Payload{} };
38+
//~^ ERROR mismatched types
2339
}

‎src/test/ui/did_you_mean/issue-42764.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n));
1313
LL | this_function_expects_a_double_option(DoubleOption::AlternativeSome(n));
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1515

16-
error: aborting due to previous error
16+
error[E0308]: mismatched types
17+
--> $DIR/issue-42764.rs:37:33
18+
|
19+
LL | let _c = Context { wrapper: Payload{} };
20+
| ^^^^^^^^^ expected struct `Wrapper`, found struct `Payload`
21+
|
22+
= note: expected type `Wrapper`
23+
found type `Payload`
24+
25+
error: aborting due to 2 previous errors
1726

1827
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)
Please sign in to comment.