1
Fork 0

Fix try wrapping expression in variant suggestion with struct field shorthand

This commit is contained in:
Michael Goulet 2022-01-11 20:22:00 -08:00
parent de9b573eed
commit dae6dc6b97
3 changed files with 92 additions and 34 deletions

View file

@ -338,9 +338,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}) })
.collect(); .collect();
if let [variant] = &compatible_variants[..] { if self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span) {
if let Ok(code) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
match &compatible_variants[..] {
[] => { /* No variants to format */ }
[variant] => {
// Just a single matching variant. // Just a single matching variant.
err.multipart_suggestion( err.span_suggestion_verbose(
expr.span,
&format!("try wrapping the expression in `{}`", variant),
format!("{}: {}({})", code, variant, code),
Applicability::MaybeIncorrect,
);
}
_ => {
// More than one matching variant.
err.span_suggestions(
expr.span,
&format!(
"try wrapping the expression in a variant of `{}`",
self.tcx.def_path_str(expected_adt.did)
),
compatible_variants
.into_iter()
.map(|variant| format!("{}: {}({})", code, variant, code)),
Applicability::MaybeIncorrect,
);
}
}
} else {
/* Can't format this without a snippet */
}
} else {
match &compatible_variants[..] {
[] => { /* No variants to format */ }
[variant] => {
// Just a single matching variant.
err.multipart_suggestion_verbose(
&format!("try wrapping the expression in `{}`", variant), &format!("try wrapping the expression in `{}`", variant),
vec![ vec![
(expr.span.shrink_to_lo(), format!("{}(", variant)), (expr.span.shrink_to_lo(), format!("{}(", variant)),
@ -348,7 +382,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
], ],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} else if compatible_variants.len() > 1 { }
_ => {
// More than one matching variant. // More than one matching variant.
err.multipart_suggestions( err.multipart_suggestions(
&format!( &format!(
@ -366,6 +401,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
} }
}
}
pub fn get_conversion_methods( pub fn get_conversion_methods(
&self, &self,

View file

@ -3,6 +3,10 @@ enum Hey<A, B> {
B(B), B(B),
} }
struct Foo {
bar: Option<i32>,
}
fn f() {} fn f() {}
fn a() -> Option<()> { fn a() -> Option<()> {
@ -40,4 +44,8 @@ fn main() {
let _: Hey<i32, bool> = false; let _: Hey<i32, bool> = false;
//~^ ERROR mismatched types //~^ ERROR mismatched types
//~| HELP try wrapping //~| HELP try wrapping
let bar = 1i32;
let _ = Foo { bar };
//~^ ERROR mismatched types
//~| HELP try wrapping
} }

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:9:5 --> $DIR/compatible-variants.rs:13:5
| |
LL | fn a() -> Option<()> { LL | fn a() -> Option<()> {
| ---------- expected `Option<()>` because of return type | ---------- expected `Option<()>` because of return type
@ -21,7 +21,7 @@ LL + Some(())
| |
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:17:5 --> $DIR/compatible-variants.rs:21:5
| |
LL | fn b() -> Result<(), ()> { LL | fn b() -> Result<(), ()> {
| -------------- expected `Result<(), ()>` because of return type | -------------- expected `Result<(), ()>` because of return type
@ -37,7 +37,7 @@ LL + Ok(())
| |
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:23:25 --> $DIR/compatible-variants.rs:27:25
| |
LL | let _: Option<()> = while false {}; LL | let _: Option<()> = while false {};
| ---------- ^^^^^^^^^^^^^^ expected enum `Option`, found `()` | ---------- ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
@ -52,7 +52,7 @@ LL | let _: Option<()> = Some(while false {});
| +++++ + | +++++ +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:27:9 --> $DIR/compatible-variants.rs:31:9
| |
LL | while false {} LL | while false {}
| ^^^^^^^^^^^^^^ expected enum `Option`, found `()` | ^^^^^^^^^^^^^^ expected enum `Option`, found `()`
@ -69,7 +69,7 @@ LL + Some(())
| |
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:31:31 --> $DIR/compatible-variants.rs:35:31
| |
LL | let _: Result<i32, i32> = 1; LL | let _: Result<i32, i32> = 1;
| ---------------- ^ expected enum `Result`, found integer | ---------------- ^ expected enum `Result`, found integer
@ -86,7 +86,7 @@ LL | let _: Result<i32, i32> = Err(1);
| ++++ + | ++++ +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:34:26 --> $DIR/compatible-variants.rs:38:26
| |
LL | let _: Option<i32> = 1; LL | let _: Option<i32> = 1;
| ----------- ^ expected enum `Option`, found integer | ----------- ^ expected enum `Option`, found integer
@ -101,7 +101,7 @@ LL | let _: Option<i32> = Some(1);
| +++++ + | +++++ +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:37:28 --> $DIR/compatible-variants.rs:41:28
| |
LL | let _: Hey<i32, i32> = 1; LL | let _: Hey<i32, i32> = 1;
| ------------- ^ expected enum `Hey`, found integer | ------------- ^ expected enum `Hey`, found integer
@ -118,7 +118,7 @@ LL | let _: Hey<i32, i32> = Hey::B(1);
| +++++++ + | +++++++ +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:40:29 --> $DIR/compatible-variants.rs:44:29
| |
LL | let _: Hey<i32, bool> = false; LL | let _: Hey<i32, bool> = false;
| -------------- ^^^^^ expected enum `Hey`, found `bool` | -------------- ^^^^^ expected enum `Hey`, found `bool`
@ -132,6 +132,19 @@ help: try wrapping the expression in `Hey::B`
LL | let _: Hey<i32, bool> = Hey::B(false); LL | let _: Hey<i32, bool> = Hey::B(false);
| +++++++ + | +++++++ +
error: aborting due to 8 previous errors error[E0308]: mismatched types
--> $DIR/compatible-variants.rs:48:19
|
LL | let _ = Foo { bar };
| ^^^ expected enum `Option`, found `i32`
|
= note: expected enum `Option<i32>`
found type `i32`
help: try wrapping the expression in `Some`
|
LL | let _ = Foo { bar: Some(bar) };
| ~~~~~~~~~~~~~~
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.