From d6b99b9c920f3c12326b0e7110236e9fe7c7ba52 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Wed, 17 Jan 2024 14:23:41 +0000
Subject: [PATCH] Use FnOnceOutput instead of FnOnce where expected

---
 compiler/rustc_middle/src/ty/print/pretty.rs  |  2 +-
 .../opaque-used-in-extraneous-argument.rs     | 21 +++++
 .../opaque-used-in-extraneous-argument.stderr | 78 +++++++++++++++++++
 3 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 tests/ui/impl-trait/opaque-used-in-extraneous-argument.rs
 create mode 100644 tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr

diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 6c9000c45f61b..4028de27cae14 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1013,7 +1013,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                                 .extend(
                                     // Group the return ty with its def id, if we had one.
                                     entry.return_ty.map(|ty| {
-                                        (tcx.require_lang_item(LangItem::FnOnce, None), ty)
+                                        (tcx.require_lang_item(LangItem::FnOnceOutput, None), ty)
                                     }),
                                 );
                         }
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.rs b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.rs
new file mode 100644
index 0000000000000..529913479ef4b
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.rs
@@ -0,0 +1,21 @@
+//! This is a regression test to avoid an ICE in diagnostics code.
+//! A typo in the compiler used to get the DefId of FnOnce, and
+//! use it where an associated item was expected.
+
+fn frob() -> impl Fn<P, Output = T> + '_ {}
+//~^ ERROR missing lifetime specifier
+//~| ERROR cannot find type `P`
+//~| ERROR cannot find type `T`
+//~| ERROR `Fn`-family traits' type parameters is subject to change
+
+fn open_parent<'path>() {
+    todo!()
+}
+
+fn main() {
+    let old_path = frob("hello");
+    //~^ ERROR function takes 0 arguments
+
+    open_parent(&old_path)
+    //~^ ERROR function takes 0 arguments
+}
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
new file mode 100644
index 0000000000000..b54b9f908b2a4
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -0,0 +1,78 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/opaque-used-in-extraneous-argument.rs:5:39
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
+   |                                       ^^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + 'static {}
+   |                                       ~~~~~~~
+
+error[E0412]: cannot find type `P` in this scope
+  --> $DIR/opaque-used-in-extraneous-argument.rs:5:22
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
+   |                      ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | fn frob<P>() -> impl Fn<P, Output = T> + '_ {}
+   |        +++
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/opaque-used-in-extraneous-argument.rs:5:34
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
+   |                                  ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | fn frob<T>() -> impl Fn<P, Output = T> + '_ {}
+   |        +++
+
+error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
+  --> $DIR/opaque-used-in-extraneous-argument.rs:5:19
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
+   |                   ^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `Fn(P) -> T`
+   |
+   = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
+   = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> $DIR/opaque-used-in-extraneous-argument.rs:16:20
+   |
+LL |     let old_path = frob("hello");
+   |                    ^^^^ -------
+   |                         |
+   |                         unexpected argument of type `&'static str`
+   |                         help: remove the extra argument
+   |
+note: function defined here
+  --> $DIR/opaque-used-in-extraneous-argument.rs:5:4
+   |
+LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
+   |    ^^^^
+
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> $DIR/opaque-used-in-extraneous-argument.rs:19:5
+   |
+LL |     open_parent(&old_path)
+   |     ^^^^^^^^^^^ ---------
+   |                 |
+   |                 unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
+   |                 help: remove the extra argument
+   |
+note: function defined here
+  --> $DIR/opaque-used-in-extraneous-argument.rs:11:4
+   |
+LL | fn open_parent<'path>() {
+   |    ^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0061, E0106, E0412, E0658.
+For more information about an error, try `rustc --explain E0061`.