From 04610ad1297bb092205be59f3faf629a96067ee3 Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Tue, 22 Nov 2022 15:57:06 +0000
Subject: [PATCH] Fix `ClosureKind::to_def_id`

---
 compiler/rustc_middle/src/ty/closure.rs       | 14 +++++++-----
 .../mismatched_types/overloaded-calls-bad.rs  | 19 +++++++++++-----
 .../overloaded-calls-bad.stderr               | 22 +++++++++++++++----
 3 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 0d6c26a582246..273a61c966c72 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -5,6 +5,7 @@ use crate::{mir, ty};
 
 use std::fmt::Write;
 
+use hir::LangItem;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -130,11 +131,14 @@ impl<'tcx> ClosureKind {
     }
 
     pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
-        match self {
-            ClosureKind::Fn => tcx.lang_items().fn_once_trait().unwrap(),
-            ClosureKind::FnMut => tcx.lang_items().fn_mut_trait().unwrap(),
-            ClosureKind::FnOnce => tcx.lang_items().fn_trait().unwrap(),
-        }
+        tcx.require_lang_item(
+            match self {
+                ClosureKind::Fn => LangItem::Fn,
+                ClosureKind::FnMut => LangItem::FnMut,
+                ClosureKind::FnOnce => LangItem::FnOnce,
+            },
+            None,
+        )
     }
 }
 
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
index 902a6ec81d60b..232cd2ba88cc2 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
@@ -20,14 +20,23 @@ impl FnOnce<(isize,)> for S {
     }
 }
 
+struct F;
+
+impl FnOnce<(i32,)> for F {
+    type Output = ();
+
+    extern "rust-call" fn call_once(self, args: (i32,)) -> Self::Output {}
+}
+
 fn main() {
-    let mut s = S {
-        x: 3,
-        y: 3,
-    };
-    let ans = s("what");    //~ ERROR mismatched types
+    let mut s = S { x: 3, y: 3 };
+    let ans = s("what");
+    //~^ ERROR mismatched types
     let ans = s();
     //~^ ERROR this function takes 1 argument but 0 arguments were supplied
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+
+    F("");
+    //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index fb3597aa85300..3a895acbdb5dd 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/overloaded-calls-bad.rs:28:17
+  --> $DIR/overloaded-calls-bad.rs:33:17
    |
 LL |     let ans = s("what");
    |               - ^^^^^^ expected `isize`, found `&str`
@@ -13,7 +13,7 @@ LL | impl FnMut<(isize,)> for S {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0057]: this function takes 1 argument but 0 arguments were supplied
-  --> $DIR/overloaded-calls-bad.rs:29:15
+  --> $DIR/overloaded-calls-bad.rs:35:15
    |
 LL |     let ans = s();
    |               ^-- an argument of type `isize` is missing
@@ -29,7 +29,7 @@ LL |     let ans = s(/* isize */);
    |                ~~~~~~~~~~~~~
 
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
-  --> $DIR/overloaded-calls-bad.rs:31:15
+  --> $DIR/overloaded-calls-bad.rs:37:15
    |
 LL |     let ans = s("burma", "shave");
    |               ^ -------  ------- argument of type `&'static str` unexpected
@@ -46,7 +46,21 @@ help: remove the extra argument
 LL |     let ans = s(/* isize */);
    |                ~~~~~~~~~~~~~
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/overloaded-calls-bad.rs:40:7
+   |
+LL |     F("");
+   |     - ^^ expected `i32`, found `&str`
+   |     |
+   |     arguments to this struct are incorrect
+   |
+note: implementation defined here
+  --> $DIR/overloaded-calls-bad.rs:25:1
+   |
+LL | impl FnOnce<(i32,)> for F {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0057, E0308.
 For more information about an error, try `rustc --explain E0057`.