diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e131089f36183..9c3484b4a3167 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -749,11 +749,42 @@ fn clean_fn_or_proc_macro( } else { hir::Constness::NotConst }; + clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } } } +/// This is needed to make it more "readable" when documenting functions using +/// `rustc_legacy_const_generics`. More information in +/// . +fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attribute]) { + for meta_item_list in attrs + .iter() + .filter(|a| a.has_name(sym::rustc_legacy_const_generics)) + .filter_map(|a| a.meta_item_list()) + { + for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.literal()).enumerate() { + match literal.kind { + ast::LitKind::Int(a, _) => { + let gen = func.generics.params.remove(0); + if let GenericParamDef { name, kind: GenericParamDefKind::Const { ty, .. } } = + gen + { + func.decl + .inputs + .values + .insert(a as _, Argument { name, type_: *ty, is_const: true }); + } else { + panic!("unexpected non const in position {}", pos); + } + } + _ => panic!("invalid arg index"), + } + } + } +} + impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) { fn clean(&self, cx: &mut DocContext<'_>) -> Function { let (generics, decl) = enter_impl_trait(cx, |cx| { @@ -779,7 +810,7 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { if name.is_empty() { name = kw::Underscore; } - Argument { name, type_: ty.clean(cx) } + Argument { name, type_: ty.clean(cx), is_const: false } }) .collect(), } @@ -798,6 +829,7 @@ impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { .map(|(i, ty)| Argument { name: name_from_pat(body.params[i].pat), type_: ty.clean(cx), + is_const: false, }) .collect(), } @@ -828,6 +860,7 @@ impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { .map(|t| Argument { type_: t.clean(cx), name: names.next().map_or(kw::Empty, |i| i.name), + is_const: false, }) .collect(), }, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 02a4fc5fb6550..1267e88f358f1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1353,6 +1353,9 @@ crate struct Arguments { crate struct Argument { crate type_: Type, crate name: Symbol, + /// This field is used to represent "const" arguments from the `rustc_legacy_const_generics` + /// feature. More information in . + crate is_const: bool, } #[derive(Clone, PartialEq, Debug)] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fdb52703edf77..25471dd726d6b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1177,6 +1177,10 @@ impl clean::FnDecl { args.push_str("
"); args_plain.push(' '); } + if input.is_const { + args.push_str("const "); + args_plain.push_str("const "); + } if !input.name.is_empty() { args.push_str(&format!("{}: ", input.name)); args_plain.push_str(&format!("{}: ", input.name)); diff --git a/src/test/rustdoc/legacy-const-generic.rs b/src/test/rustdoc/legacy-const-generic.rs new file mode 100644 index 0000000000000..46a50e2fc30b4 --- /dev/null +++ b/src/test/rustdoc/legacy-const-generic.rs @@ -0,0 +1,16 @@ +#![crate_name = "foo"] +#![feature(rustc_attrs)] + +// @has 'foo/fn.foo.html' +// @has - '//*[@class="rust fn"]' 'fn foo(x: usize, const Y: usize, z: usize) -> [usize; 3]' +#[rustc_legacy_const_generics(1)] +pub fn foo(x: usize, z: usize) -> [usize; 3] { + [x, Y, z] +} + +// @has 'foo/fn.bar.html' +// @has - '//*[@class="rust fn"]' 'fn bar(x: usize, const Y: usize, const Z: usize) -> [usize; 3]' +#[rustc_legacy_const_generics(1, 2)] +pub fn bar(x: usize) -> [usize; 3] { + [x, Y, z] +}