about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2021-02-09 23:00:33 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2021-02-09 23:00:33 +0000
commit9337d4fde89ded13243d67bec0b03f7fc553cbf9 (patch)
tree8b5b8cad42966fd1ac5746c0f1fe9e623e662435
parent94c11dfe78c9c2e81ababe51b04231db4c90d07f (diff)
downloadrust-9337d4fde89ded13243d67bec0b03f7fc553cbf9.tar.gz
rust-9337d4fde89ded13243d67bec0b03f7fc553cbf9.zip
Print closure signatures when reporting placeholder errors
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs38
-rw-r--r--src/test/ui/issues/issue-57843.stderr2
-rw-r--r--src/test/ui/lifetimes/issue-79187.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr6
5 files changed, 38 insertions, 12 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index 285666b7acb..46986d8d58b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -386,12 +386,38 @@ impl NiceRegionError<'me, 'tcx> {
             let mut note = if same_self_type {
                 let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
                 self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
-                format!(
-                    "{}`{}` must implement `{}`",
-                    if leading_ellipsis { "..." } else { "" },
-                    self_ty,
-                    expected_trait_ref.map(|tr| tr.print_only_trait_path()),
-                )
+
+                if self_ty.value.is_closure()
+                    && self
+                        .tcx()
+                        .fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id)
+                        .is_some()
+                {
+                    let closure_sig = self_ty.map(|closure| {
+                        if let ty::Closure(_, substs) = closure.kind() {
+                            self.tcx().signature_unclosure(
+                                substs.as_closure().sig(),
+                                rustc_hir::Unsafety::Normal,
+                            )
+                        } else {
+                            bug!("type is not longer closure");
+                        }
+                    });
+
+                    format!(
+                        "{}closure with signature `{}` must implement `{}`",
+                        if leading_ellipsis { "..." } else { "" },
+                        closure_sig,
+                        expected_trait_ref.map(|tr| tr.print_only_trait_path()),
+                    )
+                } else {
+                    format!(
+                        "{}`{}` must implement `{}`",
+                        if leading_ellipsis { "..." } else { "" },
+                        self_ty,
+                        expected_trait_ref.map(|tr| tr.print_only_trait_path()),
+                    )
+                }
             } else if passive_voice {
                 format!(
                     "{}`{}` would have to be implemented for the type `{}`",
diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/issues/issue-57843.stderr
index acd48b6c7e5..2ab49ec61cf 100644
--- a/src/test/ui/issues/issue-57843.stderr
+++ b/src/test/ui/issues/issue-57843.stderr
@@ -4,7 +4,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     Foo(Box::new(|_| ()));
    |         ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-57843.rs:25:18: 25:24]` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 bool)` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
diff --git a/src/test/ui/lifetimes/issue-79187.stderr b/src/test/ui/lifetimes/issue-79187.stderr
index 3627ab5ed1e..3c0439fb660 100644
--- a/src/test/ui/lifetimes/issue-79187.stderr
+++ b/src/test/ui/lifetimes/issue-79187.stderr
@@ -4,7 +4,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     thing(f);
    |     ^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-79187.rs:4:13: 4:19]` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
 
 error: aborting due to previous error
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
index 59b14eedc24..a5409582288 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr
@@ -30,7 +30,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     type Bar = impl Baz<Self, Self>;
    |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
index 59c91d52cca..91c9d459ad8 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
@@ -4,7 +4,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     type Bar = impl Baz<Self, Self>;
    |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error[E0308]: mismatched types
@@ -27,7 +27,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     type Bar = impl Baz<Self, Self>;
    |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error[E0308]: mismatched types
@@ -50,7 +50,7 @@ error: implementation of `FnOnce` is not general enough
 LL |     type Bar = impl Baz<Self, Self>;
    |                ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
    |
-   = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+   = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
    = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
 
 error: aborting due to 5 previous errors