about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-08-06 22:20:42 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-08-09 07:18:05 -0700
commit4fbbf99c509042e89572f8575c875889874edb45 (patch)
tree5a4dade869f0ef4c6c58cab6fa82484e07cb2db4
parent799b13ada59d0663e98a02744d21d2c3b08501ce (diff)
downloadrust-4fbbf99c509042e89572f8575c875889874edb45.tar.gz
rust-4fbbf99c509042e89572f8575c875889874edb45.zip
Be more accurate when mentioning type of found match arms
-rw-r--r--src/librustc/infer/error_reporting/mod.rs38
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.rs19
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.stderr22
3 files changed, 51 insertions, 28 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 8d0ead5c8fe..2ffcd2c4ace 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -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);
                     }
 
diff --git a/src/test/ui/match/match-arm-resolving-to-never.rs b/src/test/ui/match/match-arm-resolving-to-never.rs
new file mode 100644
index 00000000000..8f54023305e
--- /dev/null
+++ b/src/test/ui/match/match-arm-resolving-to-never.rs
@@ -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
+    };
+}
diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr
new file mode 100644
index 00000000000..24ce97f86e7
--- /dev/null
+++ b/src/test/ui/match/match-arm-resolving-to-never.stderr
@@ -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`.