about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-07-28 17:29:47 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-07-28 17:29:47 +0400
commit620b0f1935404828a145cc341dc1f95da67cd111 (patch)
treeb3c3bf9197f635c133ca54cb37b51be7b4d453c4
parent96b9bb4620f4d48aa25c381c7ea77e0cab48ac5b (diff)
downloadrust-620b0f1935404828a145cc341dc1f95da67cd111.tar.gz
rust-620b0f1935404828a145cc341dc1f95da67cd111.zip
improve type mismatch error for functions
This also fixes the argument names in `report_closure_arg_mismatch`
(confusing expected/found)
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs33
1 files changed, 20 insertions, 13 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 89d7c050c40..2d1b2cefad7 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -20,6 +20,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
+use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::hir::map;
 use rustc_middle::ty::{
     self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
@@ -253,8 +254,8 @@ pub trait InferCtxtExt<'tcx> {
         &self,
         span: Span,
         found_span: Option<Span>,
-        expected_ref: ty::PolyTraitRef<'tcx>,
         found: ty::PolyTraitRef<'tcx>,
+        expected: ty::PolyTraitRef<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
 
     fn suggest_fully_qualified_path(
@@ -1529,13 +1530,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         &self,
         span: Span,
         found_span: Option<Span>,
-        expected_ref: ty::PolyTraitRef<'tcx>,
         found: ty::PolyTraitRef<'tcx>,
+        expected: ty::PolyTraitRef<'tcx>,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        pub(crate) fn build_fn_sig_string<'tcx>(
+        pub(crate) fn build_fn_sig_ty<'tcx>(
             tcx: TyCtxt<'tcx>,
             trait_ref: ty::PolyTraitRef<'tcx>,
-        ) -> String {
+        ) -> Ty<'tcx> {
             let inputs = trait_ref.skip_binder().substs.type_at(1);
             let sig = match inputs.kind() {
                 ty::Tuple(inputs)
@@ -1557,10 +1558,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     abi::Abi::Rust,
                 ),
             };
-            trait_ref.rebind(sig).to_string()
+
+            tcx.mk_fn_ptr(trait_ref.rebind(sig))
         }
 
-        let argument_kind = match expected_ref.skip_binder().self_ty().kind() {
+        let argument_kind = match expected.skip_binder().self_ty().kind() {
             ty::Closure(..) => "closure",
             ty::Generator(..) => "generator",
             _ => "function",
@@ -1569,17 +1571,22 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             self.tcx.sess,
             span,
             E0631,
-            "type mismatch in {} arguments",
-            argument_kind
+            "type mismatch in {argument_kind} arguments",
         );
 
-        let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
-        err.span_label(span, found_str);
+        err.span_label(span, "expected due to this");
 
         let found_span = found_span.unwrap_or(span);
-        let expected_str =
-            format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref));
-        err.span_label(found_span, expected_str);
+        err.span_label(found_span, "found signature defined here");
+
+        let expected = build_fn_sig_ty(self.tcx, expected);
+        let found = build_fn_sig_ty(self.tcx, found);
+
+        let (expected_str, found_str) =
+            self.tcx.infer_ctxt().enter(|infcx| infcx.cmp(expected, found));
+
+        let signature_kind = format!("{argument_kind} signature");
+        err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
 
         err
     }