about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-12-18 21:41:08 +0000
committerMichael Goulet <michael@errs.io>2022-12-18 21:41:29 +0000
commitdd8897eb635abc1bb9e64876eae54e449df951ba (patch)
tree4bff89394ddd5003d6aba94b7390b9d043edc440
parent65c53c3bb6190319e210c94164b05a17997073f2 (diff)
downloadrust-dd8897eb635abc1bb9e64876eae54e449df951ba.tar.gz
rust-dd8897eb635abc1bb9e64876eae54e449df951ba.zip
Don't ICE in closure arg borrow suggestion
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs8
-rw-r--r--src/test/ui/suggestions/enum-variant-arg-mismatch.rs10
-rw-r--r--src/test/ui/suggestions/enum-variant-arg-mismatch.stderr22
3 files changed, 35 insertions, 5 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 d47a5ea3e37..6cab2db3e80 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1789,7 +1789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         self.note_conflicting_closure_bounds(cause, &mut err);
 
         if let Some(found_node) = found_node {
-            hint_missing_borrow(span, found_span, found, expected, found_node, &mut err);
+            hint_missing_borrow(span, found, expected, found_node, &mut err);
         }
 
         err
@@ -3455,7 +3455,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 /// Add a hint to add a missing borrow or remove an unnecessary one.
 fn hint_missing_borrow<'tcx>(
     span: Span,
-    found_span: Span,
     found: Ty<'tcx>,
     expected: Ty<'tcx>,
     found_node: Node<'_>,
@@ -3474,9 +3473,8 @@ fn hint_missing_borrow<'tcx>(
         }
     };
 
-    let fn_decl = found_node
-        .fn_decl()
-        .unwrap_or_else(|| span_bug!(found_span, "found node must be a function"));
+    // This could be a variant constructor, for example.
+    let Some(fn_decl) = found_node.fn_decl() else { return; };
 
     let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
 
diff --git a/src/test/ui/suggestions/enum-variant-arg-mismatch.rs b/src/test/ui/suggestions/enum-variant-arg-mismatch.rs
new file mode 100644
index 00000000000..8de5bae92fc
--- /dev/null
+++ b/src/test/ui/suggestions/enum-variant-arg-mismatch.rs
@@ -0,0 +1,10 @@
+pub enum Sexpr<'a> {
+    Ident(&'a str),
+}
+
+fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {}
+
+fn main() {
+    map(Sexpr::Ident);
+    //~^ ERROR type mismatch in function arguments
+}
diff --git a/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr b/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr
new file mode 100644
index 00000000000..f76019b7000
--- /dev/null
+++ b/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr
@@ -0,0 +1,22 @@
+error[E0631]: type mismatch in function arguments
+  --> $DIR/enum-variant-arg-mismatch.rs:8:9
+   |
+LL |     Ident(&'a str),
+   |     ----- found signature defined here
+...
+LL |     map(Sexpr::Ident);
+   |     --- ^^^^^^^^^^^^ expected due to this
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: expected function signature `fn(String) -> _`
+              found function signature `fn(&str) -> _`
+note: required by a bound in `map`
+  --> $DIR/enum-variant-arg-mismatch.rs:5:15
+   |
+LL | fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.