Be more accurate when mentioning type of found match arms
This commit is contained in:
parent
799b13ada5
commit
4fbbf99c50
3 changed files with 51 additions and 28 deletions
|
|
@ -662,19 +662,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
// `last_ty` can be `!`, `expected` will have better info when present.
|
||||
let t = self.resolve_vars_if_possible(&match exp_found {
|
||||
Some(ty::error::ExpectedFound { expected, .. }) => expected,
|
||||
_ => last_ty,
|
||||
});
|
||||
let msg = "`match` arms have incompatible types";
|
||||
err.span_label(cause.span, msg);
|
||||
if prior_arms.len() <= 4 {
|
||||
for sp in prior_arms {
|
||||
err.span_label(*sp, format!(
|
||||
"this is found to be of type `{}`",
|
||||
self.resolve_vars_if_possible(&last_ty),
|
||||
));
|
||||
err.span_label( *sp, format!("this is found to be of type `{}`", t));
|
||||
}
|
||||
} else if let Some(sp) = prior_arms.last() {
|
||||
err.span_label(*sp, format!(
|
||||
"this and all prior arms are found to be of type `{}`", last_ty,
|
||||
));
|
||||
err.span_label(
|
||||
*sp,
|
||||
format!("this and all prior arms are found to be of type `{}`", t),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1143,27 +1146,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
(_, false, _) => {
|
||||
if let Some(exp_found) = exp_found {
|
||||
let (def_id, ret_ty) = match exp_found.found.sty {
|
||||
ty::FnDef(def, _) => {
|
||||
(Some(def), Some(self.tcx.fn_sig(def).output()))
|
||||
}
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
let exp_is_struct = match exp_found.expected.sty {
|
||||
ty::Adt(def, _) => def.is_struct(),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if let (Some(def_id), Some(ret_ty)) = (def_id, ret_ty) {
|
||||
if exp_is_struct && &exp_found.expected == ret_ty.skip_binder() {
|
||||
let message = format!(
|
||||
"did you mean `{}(/* fields */)`?",
|
||||
self.tcx.def_path_str(def_id)
|
||||
);
|
||||
diag.span_label(span, message);
|
||||
}
|
||||
}
|
||||
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
||||
}
|
||||
|
||||
|
|
|
|||
19
src/test/ui/match/match-arm-resolving-to-never.rs
Normal file
19
src/test/ui/match/match-arm-resolving-to-never.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
enum E {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match E::F {
|
||||
E::A => 1,
|
||||
E::B => 2,
|
||||
E::C => 3,
|
||||
E::D => 4,
|
||||
E::E => unimplemented!(""),
|
||||
E::F => "", //~ ERROR match arms have incompatible types
|
||||
};
|
||||
}
|
||||
22
src/test/ui/match/match-arm-resolving-to-never.stderr
Normal file
22
src/test/ui/match/match-arm-resolving-to-never.stderr
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
error[E0308]: match arms have incompatible types
|
||||
--> $DIR/match-arm-resolving-to-never.rs:17:17
|
||||
|
|
||||
LL | / match E::F {
|
||||
LL | | E::A => 1,
|
||||
LL | | E::B => 2,
|
||||
LL | | E::C => 3,
|
||||
LL | | E::D => 4,
|
||||
LL | | E::E => unimplemented!(""),
|
||||
| | ------------------ this and all prior arms are found to be of type `{integer}`
|
||||
LL | | E::F => "",
|
||||
| | ^^ expected integer, found reference
|
||||
LL | | };
|
||||
| |_____- `match` arms have incompatible types
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found type `&'static str`
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue