From 7892cc3c5f6532a18338ce989ea1639af5e417b4 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 31 Jan 2023 02:59:36 +0000
Subject: [PATCH] Do not depend on Generator trait when deducing closure
 signature

---
 compiler/rustc_hir_typeck/src/closure.rs      | 20 +++++++++---------
 .../lang-items/lang-item-missing-generator.rs | 21 -------------------
 .../lang-item-missing-generator.stderr        | 15 -------------
 3 files changed, 10 insertions(+), 46 deletions(-)
 delete mode 100644 tests/ui/lang-items/lang-item-missing-generator.rs
 delete mode 100644 tests/ui/lang-items/lang-item-missing-generator.stderr

diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 329b69eff54..90c4e5b6540 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -15,6 +15,7 @@ use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::{self, Ty, TypeSuperVisitable, TypeVisitor};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map::Span;
+use rustc_span::sym;
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::error_reporting::ArgKind;
@@ -288,21 +289,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let trait_def_id = projection.trait_def_id(tcx);
 
         let is_fn = tcx.is_fn_trait(trait_def_id);
-        let gen_trait = tcx.require_lang_item(LangItem::Generator, cause_span);
-        let is_gen = gen_trait == trait_def_id;
+
+        let gen_trait = tcx.lang_items().gen_trait();
+        let is_gen = gen_trait == Some(trait_def_id);
+
         if !is_fn && !is_gen {
             debug!("not fn or generator");
             return None;
         }
 
-        if is_gen {
-            // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
-            // associated item and not yield.
-            let return_assoc_item = self.tcx.associated_item_def_ids(gen_trait)[1];
-            if return_assoc_item != projection.projection_def_id() {
-                debug!("not return assoc item of generator");
-                return None;
-            }
+        // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
+        // associated item and not yield.
+        if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return {
+            debug!("not `Return` assoc item of `Generator`");
+            return None;
         }
 
         let input_tys = if is_fn {
diff --git a/tests/ui/lang-items/lang-item-missing-generator.rs b/tests/ui/lang-items/lang-item-missing-generator.rs
deleted file mode 100644
index 9b9aff38e52..00000000000
--- a/tests/ui/lang-items/lang-item-missing-generator.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// error-pattern: requires `generator` lang_item
-#![feature(no_core, lang_items, unboxed_closures, tuple_trait)]
-#![no_core]
-
-#[lang = "sized"] pub trait Sized { }
-
-#[lang = "tuple_trait"] pub trait Tuple { }
-
-#[lang = "fn_once"]
-#[rustc_paren_sugar]
-pub trait FnOnce<Args: Tuple> {
-    type Output;
-
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-pub fn abc() -> impl FnOnce(f32) {
-    |_| {}
-}
-
-fn main() {}
diff --git a/tests/ui/lang-items/lang-item-missing-generator.stderr b/tests/ui/lang-items/lang-item-missing-generator.stderr
deleted file mode 100644
index a24fdb5fb65..00000000000
--- a/tests/ui/lang-items/lang-item-missing-generator.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0635]: unknown feature `tuple_trait`
-  --> $DIR/lang-item-missing-generator.rs:2:51
-   |
-LL | #![feature(no_core, lang_items, unboxed_closures, tuple_trait)]
-   |                                                   ^^^^^^^^^^^
-
-error: requires `generator` lang_item
-  --> $DIR/lang-item-missing-generator.rs:17:17
-   |
-LL | pub fn abc() -> impl FnOnce(f32) {
-   |                 ^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0635`.