about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2022-06-16 14:14:38 -0700
committerMichael Howell <michael@notriddle.com>2022-07-19 08:52:24 -0700
commit5271e32c463e92f1afa6c54aa9dbb6a9d8454e0d (patch)
treee581e268c8ee56abea809e888571b9a41066fdee /src
parent1169832f2ff1ce740dc3d68de2df3745ec4e1aef (diff)
downloadrust-5271e32c463e92f1afa6c54aa9dbb6a9d8454e0d.tar.gz
rust-5271e32c463e92f1afa6c54aa9dbb6a9d8454e0d.zip
Improve the function pointer docs
* Reduce duplicate impls; show only the `fn (T)` and include a sentence
  saying that there exists up to twelve of them.
* Show `Copy` and `Clone`.
* Show auto traits like `Send` and `Sync`, and blanket impls like `Any`.
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/html/format.rs32
-rw-r--r--src/test/ui/error-codes/E0118.rs2
-rw-r--r--src/test/ui/error-codes/E0118.stderr6
-rw-r--r--src/test/ui/error-codes/E0390.rs2
-rw-r--r--src/test/ui/error-codes/E0390.stderr10
-rw-r--r--src/test/ui/issues/issue-59488.stderr4
7 files changed, 44 insertions, 14 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5ddf7ea8a85..8c08f776679 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1841,7 +1841,7 @@ impl PrimitiveType {
                 Reference => [RefSimplifiedType(Mutability::Not), RefSimplifiedType(Mutability::Mut)].into_iter().collect(),
                 // FIXME: This will be wrong if we ever add inherent impls
                 // for function pointers.
-                Fn => ArrayVec::new(),
+                Fn => single(FunctionSimplifiedType(1)),
                 Never => single(NeverSimplifiedType),
             }
         })
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 291e6bc2fe4..36a47b05cb9 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1165,18 +1165,38 @@ impl clean::Impl {
 
             if let clean::Type::Tuple(types) = &self.for_ &&
                 let [clean::Type::Generic(name)] = &types[..] &&
-                (self.kind.is_fake_variadic() || self.kind.is_auto()) {
+                (self.kind.is_fake_variadic() || self.kind.is_auto())
+            {
                 // Hardcoded anchor library/core/src/primitive_docs.rs
                 // Link should match `# Trait implementations`
                 primitive_link_fragment(f, PrimitiveType::Tuple, &format!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?;
-            } else if let clean::Type::BareFunction(bare_fn) = &self.for_ &&
+            } else if let clean::BareFunction(bare_fn) = &self.for_ &&
                 let [clean::Argument { type_: clean::Type::Generic(name), .. }] = &bare_fn.decl.inputs.values[..] &&
-                (self.kind.is_fake_variadic() || self.kind.is_auto()) {
+                (self.kind.is_fake_variadic() || self.kind.is_auto())
+            {
                 // Hardcoded anchor library/core/src/primitive_docs.rs
                 // Link should match `# Trait implementations`
-                primitive_link_fragment(f, PrimitiveType::Tuple, &format!("fn ({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?;
-                // Not implemented.
-                assert!(!bare_fn.decl.c_variadic);
+
+                let hrtb = bare_fn.print_hrtb_with_space(cx);
+                let unsafety = bare_fn.unsafety.print_with_space();
+                let abi = print_abi_with_space(bare_fn.abi);
+                if f.alternate() {
+                    write!(
+                        f,
+                        "{hrtb:#}{unsafety}{abi:#}",
+                    )?;
+                } else {
+                    write!(
+                        f,
+                        "{hrtb}{unsafety}{abi}",
+                    )?;
+                }
+                let ellipsis = if bare_fn.decl.c_variadic {
+                    ", ..."
+                } else {
+                    ""
+                };
+                primitive_link_fragment(f, PrimitiveType::Tuple, &format!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?;
                 // Write output.
                 if let clean::FnRetTy::Return(ty) = &bare_fn.decl.output {
                     write!(f, " -> ")?;
diff --git a/src/test/ui/error-codes/E0118.rs b/src/test/ui/error-codes/E0118.rs
index aaef8113b8a..a61ba7bbf32 100644
--- a/src/test/ui/error-codes/E0118.rs
+++ b/src/test/ui/error-codes/E0118.rs
@@ -1,4 +1,4 @@
-impl fn(u8) { //~ ERROR E0118
+impl<T> T { //~ ERROR E0118
     fn get_state(&self) -> String {
        String::new()
     }
diff --git a/src/test/ui/error-codes/E0118.stderr b/src/test/ui/error-codes/E0118.stderr
index 296fb5d664a..8c6fa7947a8 100644
--- a/src/test/ui/error-codes/E0118.stderr
+++ b/src/test/ui/error-codes/E0118.stderr
@@ -1,8 +1,8 @@
 error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/E0118.rs:1:6
+  --> $DIR/E0118.rs:1:9
    |
-LL | impl fn(u8) {
-   |      ^^^^^^ impl requires a nominal type
+LL | impl<T> T {
+   |         ^ impl requires a nominal type
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
diff --git a/src/test/ui/error-codes/E0390.rs b/src/test/ui/error-codes/E0390.rs
index 4eb59a053b4..507483dec2e 100644
--- a/src/test/ui/error-codes/E0390.rs
+++ b/src/test/ui/error-codes/E0390.rs
@@ -4,5 +4,7 @@ struct Foo {
 
 impl *mut Foo {} //~ ERROR E0390
 
+impl fn(Foo) {} //~ ERROR E0390
+
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0390.stderr b/src/test/ui/error-codes/E0390.stderr
index e635d4ec196..0e5a9ca762b 100644
--- a/src/test/ui/error-codes/E0390.stderr
+++ b/src/test/ui/error-codes/E0390.stderr
@@ -6,6 +6,14 @@ LL | impl *mut Foo {}
    |
    = help: consider using an extension trait instead
 
-error: aborting due to previous error
+error[E0390]: cannot define inherent `impl` for primitive types
+  --> $DIR/E0390.rs:7:6
+   |
+LL | impl fn(Foo) {}
+   |      ^^^^^^^
+   |
+   = help: consider using an extension trait instead
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0390`.
diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr
index 76a47c49bba..7ce3dedaa88 100644
--- a/src/test/ui/issues/issue-59488.stderr
+++ b/src/test/ui/issues/issue-59488.stderr
@@ -96,13 +96,13 @@ LL |     assert_eq!(Foo::Bar, i);
    = help: the trait `Debug` is not implemented for `fn(usize) -> Foo {Foo::Bar}`
    = help: the following other types implement trait `Debug`:
              extern "C" fn() -> Ret
-             extern "C" fn(A) -> Ret
-             extern "C" fn(A, ...) -> Ret
              extern "C" fn(A, B) -> Ret
              extern "C" fn(A, B, ...) -> Ret
              extern "C" fn(A, B, C) -> Ret
              extern "C" fn(A, B, C, ...) -> Ret
              extern "C" fn(A, B, C, D) -> Ret
+             extern "C" fn(A, B, C, D, ...) -> Ret
+             extern "C" fn(A, B, C, D, E) -> Ret
            and 68 others
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)