From 5f447a1ca6516fefe33fa0351aaf2c27b2911d98 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 1 Feb 2025 14:27:04 -0800 Subject: [PATCH 1/2] Add test of fn pointer without argument name --- tests/rustdoc/fn-pointer-arg-name.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/rustdoc/fn-pointer-arg-name.rs b/tests/rustdoc/fn-pointer-arg-name.rs index 3bde6e9ecfa8c..212c79dfab087 100644 --- a/tests/rustdoc/fn-pointer-arg-name.rs +++ b/tests/rustdoc/fn-pointer-arg-name.rs @@ -3,3 +3,11 @@ //@ has foo/fn.f.html //@ has - '//pre[@class="rust item-decl"]' 'pub fn f(callback: fn(len: usize, foo: u32))' pub fn f(callback: fn(len: usize, foo: u32)) {} + +//@ has foo/fn.g.html +//@ has - '//pre[@class="rust item-decl"]' 'pub fn g(_: fn(_: usize, _: u32))' +pub fn g(_: fn(usize, _: u32)) {} + +//@ has foo/fn.mixed.html +//@ has - '//pre[@class="rust item-decl"]' 'pub fn mixed(_: fn(_: usize, foo: u32))' +pub fn mixed(_: fn(usize, foo: u32)) {} From b866debf3cdbc30f71b0800684236213ebbb2d8c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 1 Feb 2025 14:54:02 -0800 Subject: [PATCH 2/2] Omit argument names from function pointers that do not have argument names --- src/librustdoc/clean/mod.rs | 22 ++++++++++++++----- src/librustdoc/html/format.rs | 4 +++- tests/rustdoc/assoc-consts.rs | 2 +- tests/rustdoc/fn-pointer-arg-name.rs | 2 +- tests/rustdoc/inherent-projections.rs | 2 +- tests/rustdoc/macro-higher-kinded-function.rs | 8 +++---- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7853e311a040c..0d4ff6e7aa57f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1104,17 +1104,29 @@ fn clean_args_from_types_and_names<'tcx>( types: &[hir::Ty<'tcx>], names: &[Ident], ) -> Arguments { + fn nonempty_name(ident: &Ident) -> Option { + if ident.name == kw::Underscore || ident.name == kw::Empty { + None + } else { + Some(ident.name) + } + } + + // If at least one argument has a name, use `_` as the name of unnamed + // arguments. Otherwise omit argument names. + let default_name = if names.iter().any(|ident| nonempty_name(ident).is_some()) { + kw::Underscore + } else { + kw::Empty + }; + Arguments { values: types .iter() .enumerate() .map(|(i, ty)| Argument { type_: clean_ty(ty, cx), - name: names - .get(i) - .map(|ident| ident.name) - .filter(|ident| !ident.is_empty()) - .unwrap_or(kw::Underscore), + name: names.get(i).and_then(nonempty_name).unwrap_or(default_name), is_const: false, }) .collect(), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 20a8dc724914f..ffd457c82737c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1408,7 +1408,9 @@ impl clean::Arguments { ) -> impl Display + 'a + Captures<'tcx> { fmt::from_fn(move |f| { for (i, input) in self.values.iter().enumerate() { - write!(f, "{}: ", input.name)?; + if !input.name.is_empty() { + write!(f, "{}: ", input.name)?; + } input.type_.print(cx).fmt(f)?; if i + 1 < self.values.len() { write!(f, ", ")?; diff --git a/tests/rustdoc/assoc-consts.rs b/tests/rustdoc/assoc-consts.rs index cb8e839541c3b..247b5b180a869 100644 --- a/tests/rustdoc/assoc-consts.rs +++ b/tests/rustdoc/assoc-consts.rs @@ -45,7 +45,7 @@ pub fn f(_: &(ToString + 'static)) {} impl Bar { //@ has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \ - // "const F: fn(_: &(dyn ToString + 'static))" + // "const F: fn(&(dyn ToString + 'static))" pub const F: fn(_: &(ToString + 'static)) = f; } diff --git a/tests/rustdoc/fn-pointer-arg-name.rs b/tests/rustdoc/fn-pointer-arg-name.rs index 212c79dfab087..0ee1964511a1d 100644 --- a/tests/rustdoc/fn-pointer-arg-name.rs +++ b/tests/rustdoc/fn-pointer-arg-name.rs @@ -5,7 +5,7 @@ pub fn f(callback: fn(len: usize, foo: u32)) {} //@ has foo/fn.g.html -//@ has - '//pre[@class="rust item-decl"]' 'pub fn g(_: fn(_: usize, _: u32))' +//@ has - '//pre[@class="rust item-decl"]' 'pub fn g(_: fn(usize, u32))' pub fn g(_: fn(usize, _: u32)) {} //@ has foo/fn.mixed.html diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc/inherent-projections.rs index 4fc769f70f55c..ced4db9a490c8 100644 --- a/tests/rustdoc/inherent-projections.rs +++ b/tests/rustdoc/inherent-projections.rs @@ -13,7 +13,7 @@ impl Owner { } // Make sure we handle bound vars correctly. -//@ has 'inherent_projections/fn.user.html' '//pre[@class="rust item-decl"]' "user(_: for<'a> fn(_: Carrier<'a>::Focus))" +//@ has 'inherent_projections/fn.user.html' '//pre[@class="rust item-decl"]' "user(_: for<'a> fn(Carrier<'a>::Focus))" pub fn user(_: for<'a> fn(Carrier<'a>::Focus)) {} pub struct Carrier<'a>(&'a ()); diff --git a/tests/rustdoc/macro-higher-kinded-function.rs b/tests/rustdoc/macro-higher-kinded-function.rs index f14125d13091c..738ea8fb3f153 100644 --- a/tests/rustdoc/macro-higher-kinded-function.rs +++ b/tests/rustdoc/macro-higher-kinded-function.rs @@ -11,10 +11,10 @@ macro_rules! gen { } //@ has 'foo/struct.Providers.html' -//@ has - '//*[@class="rust item-decl"]//code' "pub a: for<'tcx> fn(_: TyCtxt<'tcx>, _: u8) -> i8," -//@ has - '//*[@class="rust item-decl"]//code' "pub b: for<'tcx> fn(_: TyCtxt<'tcx>, _: u16) -> i16," -//@ has - '//*[@id="structfield.a"]/code' "a: for<'tcx> fn(_: TyCtxt<'tcx>, _: u8) -> i8" -//@ has - '//*[@id="structfield.b"]/code' "b: for<'tcx> fn(_: TyCtxt<'tcx>, _: u16) -> i16" +//@ has - '//*[@class="rust item-decl"]//code' "pub a: for<'tcx> fn(TyCtxt<'tcx>, u8) -> i8," +//@ has - '//*[@class="rust item-decl"]//code' "pub b: for<'tcx> fn(TyCtxt<'tcx>, u16) -> i16," +//@ has - '//*[@id="structfield.a"]/code' "a: for<'tcx> fn(TyCtxt<'tcx>, u8) -> i8" +//@ has - '//*[@id="structfield.b"]/code' "b: for<'tcx> fn(TyCtxt<'tcx>, u16) -> i16" gen! { (a, 'tcx, [u8], [i8]) (b, 'tcx, [u16], [i16])