diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index c7ca0134f9c..7572b8c6f4a 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -108,7 +108,7 @@ def check_type(ty): elif ty["kind"] == "function_pointer": for param in ty["inner"]["generic_params"]: check_generic_param(param) - check_decl(ty["inner"]["inner"]) + check_decl(ty["inner"]["decl"]) elif ty["kind"] == "qualified_path": check_type(ty["inner"]["self_type"]) check_type(ty["inner"]["trait"]) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index e021faa5041..af44ab9868e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -225,15 +225,22 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -fn stringify_header(header: &rustc_hir::FnHeader) -> String { - let mut s = String::from(header.unsafety.prefix_str()); - if header.asyncness == rustc_hir::IsAsync::Async { - s.push_str("async ") +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> Vec { + let mut v = Vec::new(); + + if let rustc_hir::Unsafety::Unsafe = header.unsafety { + v.push(Modifiers::Unsafe); } - if header.constness == rustc_hir::Constness::Const { - s.push_str("const ") + + if let rustc_hir::IsAsync::Async = header.asyncness { + v.push(Modifiers::Async); } - s + + if let rustc_hir::Constness::Const = header.constness { + v.push(Modifiers::Const); + } + + v } impl From for Function { @@ -242,7 +249,7 @@ impl From for Function { Function { decl: decl.into(), generics: generics.into(), - header: stringify_header(&header), + header: from_fn_header(&header), abi: header.abi.to_string(), } } @@ -364,7 +371,11 @@ impl From for FunctionPointer { fn from(bare_decl: clean::BareFunctionDecl) -> Self { let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; FunctionPointer { - is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, + header: if let rustc_hir::Unsafety::Unsafe = unsafety { + vec![Modifiers::Unsafe] + } else { + vec![] + }, generic_params: generic_params.into_iter().map(Into::into).collect(), decl: decl.into(), abi: abi.to_string(), @@ -439,7 +450,7 @@ crate fn from_function_method(function: clean::Function, has_body: bool) -> Meth Method { decl: decl.into(), generics: generics.into(), - header: stringify_header(&header), + header: from_fn_header(&header), abi: header.abi.to_string(), has_body, } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 876b1b56dee..b31276c9dcb 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -243,7 +243,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 3, + format_version: 4, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index f4b8dc9a3ad..790f9d62d8a 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -281,11 +281,20 @@ pub enum StructType { Unit, } +#[non_exhaustive] +#[serde(rename_all = "snake_case")] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub enum Modifiers { + Const, + Unsafe, + Async, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: String, + pub header: Vec, pub abi: String, } @@ -293,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: String, + pub header: Vec, pub abi: String, pub has_body: bool, } @@ -404,9 +413,9 @@ pub enum Type { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct FunctionPointer { - pub is_unsafe: bool, - pub generic_params: Vec, pub decl: FnDecl, + pub generic_params: Vec, + pub header: Vec, pub abi: String, } diff --git a/src/test/rustdoc-json/fn_pointer/header.rs b/src/test/rustdoc-json/fn_pointer/header.rs new file mode 100644 index 00000000000..a5038e0cd2a --- /dev/null +++ b/src/test/rustdoc-json/fn_pointer/header.rs @@ -0,0 +1,5 @@ +// @has header.json "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header" "[]" +pub type FnPointer = fn(); + +// @has - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header" '["unsafe"]' +pub type UnsafePointer = unsafe fn(); diff --git a/src/test/rustdoc-json/fns/header.rs b/src/test/rustdoc-json/fns/header.rs new file mode 100644 index 00000000000..fb4f89db267 --- /dev/null +++ b/src/test/rustdoc-json/fns/header.rs @@ -0,0 +1,20 @@ +// edition:2018 + +// @has header.json "$.index[*][?(@.name=='nothing_fn')].inner.header" "[]" +pub fn nothing_fn() {} + +// @has - "$.index[*][?(@.name=='const_fn')].inner.header" '["const"]' +pub const fn const_fn() {} + +// @has - "$.index[*][?(@.name=='async_fn')].inner.header" '["async"]' +pub async fn async_fn() {} + +// @count - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" 2 +// @has - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" '"async"' +// @has - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header[*]" '"unsafe"' +pub async unsafe fn async_unsafe_fn() {} + +// @count - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" 2 +// @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"const"' +// @has - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header[*]" '"unsafe"' +pub const unsafe fn const_unsafe_fn() {} diff --git a/src/test/rustdoc-json/methods/header.rs b/src/test/rustdoc-json/methods/header.rs new file mode 100644 index 00000000000..27a6ec04730 --- /dev/null +++ b/src/test/rustdoc-json/methods/header.rs @@ -0,0 +1,24 @@ +// edition:2018 + +pub struct Foo; + +impl Foo { + // @has header.json "$.index[*][?(@.name=='nothing_meth')].inner.header" "[]" + pub fn nothing_meth() {} + + // @has - "$.index[*][?(@.name=='const_meth')].inner.header" '["const"]' + pub const fn const_meth() {} + + // @has - "$.index[*][?(@.name=='async_meth')].inner.header" '["async"]' + pub async fn async_meth() {} + + // @count - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" 2 + // @has - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" '"async"' + // @has - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header[*]" '"unsafe"' + pub async unsafe fn async_unsafe_meth() {} + + // @count - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" 2 + // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"const"' + // @has - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header[*]" '"unsafe"' + pub const unsafe fn const_unsafe_meth() {} +}