From a26fa74d3cba37a6e1df2dffae00c522546350a3 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 13:48:10 -0500 Subject: [PATCH 1/5] Make `header` a vec of modifiers, make FunctionPointer consistent with Function and Method. --- src/etc/check_missing_items.py | 2 +- src/librustdoc/json/conversions.rs | 31 +++++++++++++++------- src/librustdoc/json/mod.rs | 2 +- src/rustdoc-json-types/lib.rs | 17 +++++++++--- src/test/rustdoc-json/fn_pointer/header.rs | 5 ++++ src/test/rustdoc-json/fns/header.rs | 20 ++++++++++++++ src/test/rustdoc-json/methods/header.rs | 24 +++++++++++++++++ 7 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 src/test/rustdoc-json/fn_pointer/header.rs create mode 100644 src/test/rustdoc-json/fns/header.rs create mode 100644 src/test/rustdoc-json/methods/header.rs diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index c7ca0134f9ce1..7572b8c6f4a8c 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 e021faa50412e..af44ab9868eff 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 let rustc_hir::IsAsync::Async = header.asyncness { + v.push(Modifiers::Async); } - if header.constness == rustc_hir::Constness::Const { - s.push_str("const ") + + if let rustc_hir::Constness::Const = header.constness { + v.push(Modifiers::Const); } - s + + 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 876b1b56dee6d..b31276c9dcb7f 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 f4b8dc9a3ad2b..790f9d62d8a9c 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 0000000000000..a5038e0cd2aa8 --- /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 0000000000000..fb4f89db26733 --- /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 0000000000000..27a6ec047300d --- /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() {} +} From ce02b7f7a6f554dbf80b7cabc09c3d84d92d0c3a Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 15:45:50 -0500 Subject: [PATCH 2/5] Add comment + move derive helper --- src/rustdoc-json-types/lib.rs | 2 +- src/test/rustdoc-json/fns/header.rs | 2 ++ src/test/rustdoc-json/methods/header.rs | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 790f9d62d8a9c..20bae0f14a2f4 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -282,8 +282,8 @@ pub enum StructType { } #[non_exhaustive] -#[serde(rename_all = "snake_case")] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum Modifiers { Const, Unsafe, diff --git a/src/test/rustdoc-json/fns/header.rs b/src/test/rustdoc-json/fns/header.rs index fb4f89db26733..29741dd50dadc 100644 --- a/src/test/rustdoc-json/fns/header.rs +++ b/src/test/rustdoc-json/fns/header.rs @@ -18,3 +18,5 @@ pub async unsafe fn async_unsafe_fn() {} // @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() {} + +// It's impossible for a function to be both const and async, so no test for that diff --git a/src/test/rustdoc-json/methods/header.rs b/src/test/rustdoc-json/methods/header.rs index 27a6ec047300d..50a3db75ef395 100644 --- a/src/test/rustdoc-json/methods/header.rs +++ b/src/test/rustdoc-json/methods/header.rs @@ -21,4 +21,6 @@ impl Foo { // @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() {} + + // It's impossible for a method to be both const and async, so no test for that } From 0a91daeaa33e4ae71e0be405cdddba741b72aa7f Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 16:04:14 -0500 Subject: [PATCH 3/5] Vec -> HashSet --- src/librustdoc/json/conversions.rs | 17 ++++++++++------- src/rustdoc-json-types/lib.rs | 10 +++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index af44ab9868eff..de0240f28f7cc 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -14,6 +14,7 @@ use rustdoc_json_types::*; use crate::clean; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; +use std::collections::HashSet; impl JsonRenderer<'_> { pub(super) fn convert_item(&self, item: clean::Item) -> Option { @@ -225,19 +226,19 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -crate fn from_fn_header(header: &rustc_hir::FnHeader) -> Vec { - let mut v = Vec::new(); +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { + let mut v = HashSet::new(); if let rustc_hir::Unsafety::Unsafe = header.unsafety { - v.push(Modifiers::Unsafe); + v.insert(Modifiers::Unsafe); } if let rustc_hir::IsAsync::Async = header.asyncness { - v.push(Modifiers::Async); + v.insert(Modifiers::Async); } if let rustc_hir::Constness::Const = header.constness { - v.push(Modifiers::Const); + v.insert(Modifiers::Const); } v @@ -372,9 +373,11 @@ impl From for FunctionPointer { let clean::BareFunctionDecl { unsafety, generic_params, decl, abi } = bare_decl; FunctionPointer { header: if let rustc_hir::Unsafety::Unsafe = unsafety { - vec![Modifiers::Unsafe] + let mut hs = HashSet::new(); + hs.insert(Modifiers::Unsafe); + hs } else { - vec![] + HashSet::new() }, generic_params: generic_params.into_iter().map(Into::into).collect(), decl: decl.into(), diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 20bae0f14a2f4..a2f323699c199 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -3,7 +3,7 @@ //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] //! struct is the root of the JSON blob and all other items are contained within. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use serde::{Deserialize, Serialize}; @@ -282,7 +282,7 @@ pub enum StructType { } #[non_exhaustive] -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] pub enum Modifiers { Const, @@ -294,7 +294,7 @@ pub enum Modifiers { pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: Vec, + pub header: HashSet, pub abi: String, } @@ -302,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: Vec, + pub header: HashSet, pub abi: String, pub has_body: bool, } @@ -415,7 +415,7 @@ pub enum Type { pub struct FunctionPointer { pub decl: FnDecl, pub generic_params: Vec, - pub header: Vec, + pub header: HashSet, pub abi: String, } From ffa5280b0ed19400e2095ce6cc2eb6e888d6bd01 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Mon, 8 Feb 2021 16:17:00 -0500 Subject: [PATCH 4/5] Allow default hash types in conversion --- src/librustdoc/json/conversions.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index de0240f28f7cc..60197a0dc1cf5 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -2,6 +2,8 @@ //! the `clean` types but with some fields removed or stringified to simplify the output and not //! expose unstable compiler internals. +#![allow(rustc::default_hash_types)] + use std::convert::From; use rustc_ast::ast; From be4ea06643a5bd4ff3cb91efdaafd7acb070cb30 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 12 Feb 2021 23:24:09 -0500 Subject: [PATCH 5/5] Modifiers -> Qualifiers --- src/librustdoc/json/conversions.rs | 10 +++++----- src/rustdoc-json-types/lib.rs | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 60197a0dc1cf5..691a7fb2a4ed3 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -228,19 +228,19 @@ crate fn from_ctor_kind(struct_type: CtorKind) -> StructType { } } -crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { +crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet { let mut v = HashSet::new(); if let rustc_hir::Unsafety::Unsafe = header.unsafety { - v.insert(Modifiers::Unsafe); + v.insert(Qualifiers::Unsafe); } if let rustc_hir::IsAsync::Async = header.asyncness { - v.insert(Modifiers::Async); + v.insert(Qualifiers::Async); } if let rustc_hir::Constness::Const = header.constness { - v.insert(Modifiers::Const); + v.insert(Qualifiers::Const); } v @@ -376,7 +376,7 @@ impl From for FunctionPointer { FunctionPointer { header: if let rustc_hir::Unsafety::Unsafe = unsafety { let mut hs = HashSet::new(); - hs.insert(Modifiers::Unsafe); + hs.insert(Qualifiers::Unsafe); hs } else { HashSet::new() diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index a2f323699c199..eae27a4a823cd 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -284,7 +284,7 @@ pub enum StructType { #[non_exhaustive] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "snake_case")] -pub enum Modifiers { +pub enum Qualifiers { Const, Unsafe, Async, @@ -294,7 +294,7 @@ pub enum Modifiers { pub struct Function { pub decl: FnDecl, pub generics: Generics, - pub header: HashSet, + pub header: HashSet, pub abi: String, } @@ -302,7 +302,7 @@ pub struct Function { pub struct Method { pub decl: FnDecl, pub generics: Generics, - pub header: HashSet, + pub header: HashSet, pub abi: String, pub has_body: bool, } @@ -415,7 +415,7 @@ pub enum Type { pub struct FunctionPointer { pub decl: FnDecl, pub generic_params: Vec, - pub header: HashSet, + pub header: HashSet, pub abi: String, }