about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs11
-rw-r--r--tests/ui/mismatched_types/issue-118510.rs10
-rw-r--r--tests/ui/mismatched_types/issue-118510.stderr26
3 files changed, 45 insertions, 2 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 d5e1efb9663..6b231a30ea7 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2112,7 +2112,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             && !expected_inputs.is_empty()
             && expected_inputs.len() == found_inputs.len()
             && let Some(typeck) = &self.typeck_results
-            && let Res::Def(_, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id)
+            && let Res::Def(res_kind, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id)
+            && res_kind.is_fn_like()
         {
             let closure: Vec<_> = self
                 .tcx
@@ -2155,7 +2156,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             .map(|(name, ty)| {
                 format!(
                     "{name}{}",
-                    if ty.has_infer_types() { String::new() } else { format!(": {ty}") }
+                    if ty.has_infer_types() {
+                        String::new()
+                    } else if ty.references_error() {
+                        ": /* type */".to_string()
+                    } else {
+                        format!(": {ty}")
+                    }
                 )
             })
             .collect();
diff --git a/tests/ui/mismatched_types/issue-118510.rs b/tests/ui/mismatched_types/issue-118510.rs
new file mode 100644
index 00000000000..86b9d44a373
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-118510.rs
@@ -0,0 +1,10 @@
+pub enum Sexpr<'a, S> {
+    Ident(&'a mut S),
+}
+
+fn map<Foo, T, F: FnOnce(&Foo) -> T>(f: F) {}
+
+fn main() {
+    map(Sexpr::Ident);
+    //~^ ERROR type mismatch in function arguments
+}
diff --git a/tests/ui/mismatched_types/issue-118510.stderr b/tests/ui/mismatched_types/issue-118510.stderr
new file mode 100644
index 00000000000..e8bf92d9047
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-118510.stderr
@@ -0,0 +1,26 @@
+error[E0631]: type mismatch in function arguments
+  --> $DIR/issue-118510.rs:8:9
+   |
+LL |     Ident(&'a mut S),
+   |     ----- found signature defined here
+...
+LL |     map(Sexpr::Ident);
+   |     --- ^^^^^^^^^^^^ expected due to this
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected function signature `for<'a> fn(&'a _) -> _`
+              found function signature `fn(&mut _) -> _`
+note: required by a bound in `map`
+  --> $DIR/issue-118510.rs:5:19
+   |
+LL | fn map<Foo, T, F: FnOnce(&Foo) -> T>(f: F) {}
+   |                   ^^^^^^^^^^^^^^^^^ required by this bound in `map`
+help: consider wrapping the function in a closure
+   |
+LL |     map(|arg0| Sexpr::Ident(&mut *arg0));
+   |         ++++++             ++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0631`.