summaryrefslogtreecommitdiffstats
path: root/src/test/rustdoc-json
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/rustdoc-json')
-rw-r--r--src/test/rustdoc-json/assoc_items.rs29
-rw-r--r--src/test/rustdoc-json/assoc_type.rs22
-rw-r--r--src/test/rustdoc-json/blanket_impls.rs9
-rw-r--r--src/test/rustdoc-json/doc_hidden_failure.rs22
-rw-r--r--src/test/rustdoc-json/enums/variant_struct.rs11
-rw-r--r--src/test/rustdoc-json/enums/variant_tuple_struct.rs8
-rw-r--r--src/test/rustdoc-json/fn_pointer/abi.rs25
-rw-r--r--src/test/rustdoc-json/fn_pointer/generics.rs14
-rw-r--r--src/test/rustdoc-json/fn_pointer/qualifiers.rs9
-rw-r--r--src/test/rustdoc-json/fns/abi.rs25
-rw-r--r--src/test/rustdoc-json/fns/generic_args.rs71
-rw-r--r--src/test/rustdoc-json/fns/generic_returns.rs21
-rw-r--r--src/test/rustdoc-json/fns/generics.rs26
-rw-r--r--src/test/rustdoc-json/fns/qualifiers.rs33
-rw-r--r--src/test/rustdoc-json/generic-associated-types/gats.rs44
-rw-r--r--src/test/rustdoc-json/generic_impl.rs24
-rw-r--r--src/test/rustdoc-json/glob_import.rs24
-rw-r--r--src/test/rustdoc-json/impls/blanket_with_local.rs18
-rw-r--r--src/test/rustdoc-json/keyword.rs21
-rw-r--r--src/test/rustdoc-json/lifetime/longest.rs33
-rw-r--r--src/test/rustdoc-json/lifetime/outlives.rs23
-rw-r--r--src/test/rustdoc-json/methods/abi.rs55
-rw-r--r--src/test/rustdoc-json/methods/qualifiers.rs37
-rw-r--r--src/test/rustdoc-json/nested.rs30
-rw-r--r--src/test/rustdoc-json/output_generics.rs38
-rw-r--r--src/test/rustdoc-json/primitive.rs14
-rw-r--r--src/test/rustdoc-json/primitive_overloading.rs17
-rw-r--r--src/test/rustdoc-json/primitives.rs22
-rw-r--r--src/test/rustdoc-json/reexport/auxiliary/pub-struct.rs1
-rw-r--r--src/test/rustdoc-json/reexport/glob_extern.rs18
-rw-r--r--src/test/rustdoc-json/reexport/glob_private.rs32
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod.rs17
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs20
-rw-r--r--src/test/rustdoc-json/reexport/macro.rs17
-rw-r--r--src/test/rustdoc-json/reexport/private_twice_one_inline.rs18
-rw-r--r--src/test/rustdoc-json/reexport/private_two_names.rs17
-rw-r--r--src/test/rustdoc-json/reexport/rename_private.rs14
-rw-r--r--src/test/rustdoc-json/reexport/rename_public.rs17
-rw-r--r--src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs15
-rw-r--r--src/test/rustdoc-json/reexport/simple_private.rs15
-rw-r--r--src/test/rustdoc-json/reexport/simple_public.rs18
-rw-r--r--src/test/rustdoc-json/return_private.rs15
-rw-r--r--src/test/rustdoc-json/stripped_modules.rs21
-rw-r--r--src/test/rustdoc-json/structs/plain_empty.rs6
-rw-r--r--src/test/rustdoc-json/structs/tuple.rs5
-rw-r--r--src/test/rustdoc-json/structs/unit.rs5
-rw-r--r--src/test/rustdoc-json/structs/with_generics.rs14
-rw-r--r--src/test/rustdoc-json/structs/with_primitives.rs10
-rw-r--r--src/test/rustdoc-json/traits/has_body.rs21
-rw-r--r--src/test/rustdoc-json/traits/implementors.rs19
-rw-r--r--src/test/rustdoc-json/traits/supertrait.rs26
-rw-r--r--src/test/rustdoc-json/type/dyn.rs21
-rw-r--r--src/test/rustdoc-json/type/fn_lifetime.rs28
-rw-r--r--src/test/rustdoc-json/type/generic_default.rs33
-rw-r--r--src/test/rustdoc-json/unions/impl.rs15
-rw-r--r--src/test/rustdoc-json/unions/union.rs7
56 files changed, 1190 insertions, 0 deletions
diff --git a/src/test/rustdoc-json/assoc_items.rs b/src/test/rustdoc-json/assoc_items.rs
new file mode 100644
index 000000000..2ee64c9f6
--- /dev/null
+++ b/src/test/rustdoc-json/assoc_items.rs
@@ -0,0 +1,29 @@
+#![no_std]
+
+// @has assoc_items.json
+
+pub struct Simple;
+
+impl Simple {
+ // @has - "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
+ pub const CONSTANT: usize = 0;
+}
+
+pub trait EasyToImpl {
+ // @has - "$.index[*][?(@.name=='ToDeclare')].kind" \"assoc_type\"
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default" null
+ type ToDeclare;
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].kind" \"assoc_const\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" null
+ const AN_ATTRIBUTE: usize;
+}
+
+impl EasyToImpl for Simple {
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.kind" \"primitive\"
+ // @has - "$.index[*][?(@.name=='ToDeclare')].inner.default.inner" \"usize\"
+ type ToDeclare = usize;
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.kind" \"primitive\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.inner" \"usize\"
+ // @has - "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" \"12\"
+ const AN_ATTRIBUTE: usize = 12;
+}
diff --git a/src/test/rustdoc-json/assoc_type.rs b/src/test/rustdoc-json/assoc_type.rs
new file mode 100644
index 000000000..716bb3d28
--- /dev/null
+++ b/src/test/rustdoc-json/assoc_type.rs
@@ -0,0 +1,22 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98547>.
+
+// @has assoc_type.json
+// @has - "$.index[*][?(@.name=='Trait')]"
+// @has - "$.index[*][?(@.name=='AssocType')]"
+// @has - "$.index[*][?(@.name=='S')]"
+// @has - "$.index[*][?(@.name=='S2')]"
+
+pub trait Trait {
+ type AssocType;
+}
+
+impl<T> Trait for T {
+ type AssocType = Self;
+}
+
+pub struct S;
+
+/// Not needed for the #98547 ICE to occur, but added to maximize the chance of
+/// getting an ICE in the future. See
+/// <https://github.com/rust-lang/rust/pull/98548#discussion_r908219164>
+pub struct S2;
diff --git a/src/test/rustdoc-json/blanket_impls.rs b/src/test/rustdoc-json/blanket_impls.rs
new file mode 100644
index 000000000..edf1a9fe2
--- /dev/null
+++ b/src/test/rustdoc-json/blanket_impls.rs
@@ -0,0 +1,9 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98658>
+
+#![no_std]
+
+// @has blanket_impls.json
+// @has - "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
+// @has - "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
+// @has - "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
+pub struct ForBlanketTryFromImpl;
diff --git a/src/test/rustdoc-json/doc_hidden_failure.rs b/src/test/rustdoc-json/doc_hidden_failure.rs
new file mode 100644
index 000000000..5c4ccf996
--- /dev/null
+++ b/src/test/rustdoc-json/doc_hidden_failure.rs
@@ -0,0 +1,22 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98007>.
+
+#![feature(no_core)]
+#![no_core]
+
+mod auto {
+ mod action_row {
+ pub struct ActionRowBuilder;
+ }
+
+ #[doc(hidden)]
+ pub mod builders {
+ pub use super::action_row::ActionRowBuilder;
+ }
+}
+
+// @count doc_hidden_failure.json "$.index[*][?(@.name=='builders')]" 2
+pub use auto::*;
+
+pub mod builders {
+ pub use crate::auto::builders::*;
+}
diff --git a/src/test/rustdoc-json/enums/variant_struct.rs b/src/test/rustdoc-json/enums/variant_struct.rs
new file mode 100644
index 000000000..fcd92887c
--- /dev/null
+++ b/src/test/rustdoc-json/enums/variant_struct.rs
@@ -0,0 +1,11 @@
+// @has variant_struct.json "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
+pub enum EnumStruct {
+ // @has - "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\"
+ // @has - "$.index[*][?(@.name=='x')].kind" \"struct_field\"
+ // @has - "$.index[*][?(@.name=='y')].kind" \"struct_field\"
+ VariantS {
+ x: u32,
+ y: String,
+ },
+}
diff --git a/src/test/rustdoc-json/enums/variant_tuple_struct.rs b/src/test/rustdoc-json/enums/variant_tuple_struct.rs
new file mode 100644
index 000000000..ac3e72e29
--- /dev/null
+++ b/src/test/rustdoc-json/enums/variant_tuple_struct.rs
@@ -0,0 +1,8 @@
+// @has variant_tuple_struct.json "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
+pub enum EnumTupleStruct {
+ // @has - "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\"
+ // @has - "$.index[*][?(@.name=='0')].kind" \"struct_field\"
+ // @has - "$.index[*][?(@.name=='1')].kind" \"struct_field\"
+ VariantA(u32, String),
+}
diff --git a/src/test/rustdoc-json/fn_pointer/abi.rs b/src/test/rustdoc-json/fn_pointer/abi.rs
new file mode 100644
index 000000000..eef20e60a
--- /dev/null
+++ b/src/test/rustdoc-json/fn_pointer/abi.rs
@@ -0,0 +1,25 @@
+// ignore-tidy-linelength
+
+#![feature(abi_vectorcall)]
+#![feature(c_unwind)]
+
+// @is abi.json "$.index[*][?(@.name=='AbiRust')].inner.type.inner.header.abi" \"Rust\"
+pub type AbiRust = fn();
+
+// @is - "$.index[*][?(@.name=='AbiC')].inner.type.inner.header.abi" '{"C": {"unwind": false}}'
+pub type AbiC = extern "C" fn();
+
+// @is - "$.index[*][?(@.name=='AbiSystem')].inner.type.inner.header.abi" '{"System": {"unwind": false}}'
+pub type AbiSystem = extern "system" fn();
+
+// @is - "$.index[*][?(@.name=='AbiCUnwind')].inner.type.inner.header.abi" '{"C": {"unwind": true}}'
+pub type AbiCUnwind = extern "C-unwind" fn();
+
+// @is - "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type.inner.header.abi" '{"System": {"unwind": true}}'
+pub type AbiSystemUnwind = extern "system-unwind" fn();
+
+// @is - "$.index[*][?(@.name=='AbiVecorcall')].inner.type.inner.header.abi.Other" '"\"vectorcall\""'
+pub type AbiVecorcall = extern "vectorcall" fn();
+
+// @is - "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type.inner.header.abi.Other" '"\"vectorcall-unwind\""'
+pub type AbiVecorcallUnwind = extern "vectorcall-unwind" fn();
diff --git a/src/test/rustdoc-json/fn_pointer/generics.rs b/src/test/rustdoc-json/fn_pointer/generics.rs
new file mode 100644
index 000000000..646f720e6
--- /dev/null
+++ b/src/test/rustdoc-json/fn_pointer/generics.rs
@@ -0,0 +1,14 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @count generics.json "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][0]" '"val"'
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.inputs[0][1].inner.lifetime" \"\'c\"
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.decl.output" '{ "kind": "primitive", "inner": "i32" }'
+// @count - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[*]" 1
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].name" \"\'c\"
+// @is - "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type.inner.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+pub type WithHigherRankTraitBounds = for<'c> fn(val: &'c i32) -> i32;
diff --git a/src/test/rustdoc-json/fn_pointer/qualifiers.rs b/src/test/rustdoc-json/fn_pointer/qualifiers.rs
new file mode 100644
index 000000000..381922085
--- /dev/null
+++ b/src/test/rustdoc-json/fn_pointer/qualifiers.rs
@@ -0,0 +1,9 @@
+// @is qualifiers.json "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.unsafe" false
+// @is - "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.const" false
+// @is - "$.index[*][?(@.name=='FnPointer')].inner.type.inner.header.async" false
+pub type FnPointer = fn();
+
+// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.unsafe" true
+// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.const" false
+// @is - "$.index[*][?(@.name=='UnsafePointer')].inner.type.inner.header.async" false
+pub type UnsafePointer = unsafe fn();
diff --git a/src/test/rustdoc-json/fns/abi.rs b/src/test/rustdoc-json/fns/abi.rs
new file mode 100644
index 000000000..16b579130
--- /dev/null
+++ b/src/test/rustdoc-json/fns/abi.rs
@@ -0,0 +1,25 @@
+// ignore-tidy-linelength
+
+#![feature(abi_vectorcall)]
+#![feature(c_unwind)]
+
+// @is abi.json "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+pub fn abi_rust() {}
+
+// @is - "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+pub extern "C" fn abi_c() {}
+
+// @is - "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+pub extern "system" fn abi_system() {}
+
+// @is - "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+pub extern "C-unwind" fn abi_c_unwind() {}
+
+// @is - "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+pub extern "system-unwind" fn abi_system_unwind() {}
+
+// @is - "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+pub extern "vectorcall" fn abi_vectorcall() {}
+
+// @is - "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
diff --git a/src/test/rustdoc-json/fns/generic_args.rs b/src/test/rustdoc-json/fns/generic_args.rs
new file mode 100644
index 000000000..69150443c
--- /dev/null
+++ b/src/test/rustdoc-json/fns/generic_args.rs
@@ -0,0 +1,71 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @set foo = generic_args.json "$.index[*][?(@.name=='Foo')].id"
+pub trait Foo {}
+
+// @set generic_foo = generic_args.json "$.index[*][?(@.name=='GenericFoo')].id"
+pub trait GenericFoo<'a> {}
+
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.where_predicates" "[]"
+// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].name" '"F"'
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.default" 'null'
+// @count - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='generics')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" '$foo'
+// @count - "$.index[*][?(@.name=='generics')].inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][0]" '"f"'
+// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].kind" '"generic"'
+// @is - "$.index[*][?(@.name=='generics')].inner.decl.inputs[0][1].inner" '"F"'
+pub fn generics<F: Foo>(f: F) {}
+
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.where_predicates" "[]"
+// @count - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].name" '"impl Foo"'
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $foo
+// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][0]" '"f"'
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @count - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[*]" 1
+// @is - "$.index[*][?(@.name=='impl_trait')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $foo
+pub fn impl_trait(f: impl Foo) {}
+
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.params[*]" 3
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].name" '"F"'
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "synthetic": false}}'
+// @count - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[*]" 3
+// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][0]" '"f"'
+// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].kind" '"generic"'
+// @is - "$.index[*][?(@.name=='where_clase')].inner.decl.inputs[0][1].inner" '"F"'
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[*]" 3
+
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F", "kind": "generic"}'
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.type" '{"inner": "G", "kind": "generic"}'
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.inner.id" $generic_foo
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\"
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[1].bound_predicate.generic_params" "[]"
+
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.lifetime" \"\'b\"
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.type.inner.type" '{"inner": "H", "kind": "generic"}'
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.inner.id" $foo
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]"
+// @count - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[*]" 1
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\"
+// @is - "$.index[*][?(@.name=='where_clase')].inner.generics.where_predicates[2].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }'
+pub fn where_clase<F, G, H>(f: F, g: G, h: H)
+where
+ F: Foo,
+ G: for<'a> GenericFoo<'a>,
+ for<'b> &'b H: Foo,
+{
+}
diff --git a/src/test/rustdoc-json/fns/generic_returns.rs b/src/test/rustdoc-json/fns/generic_returns.rs
new file mode 100644
index 000000000..1a0f33fe3
--- /dev/null
+++ b/src/test/rustdoc-json/fns/generic_returns.rs
@@ -0,0 +1,21 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @count generic_returns.json "$.index[*][?(@.name=='generic_returns')].inner.items[*]" 2
+
+// @set foo = - "$.index[*][?(@.name=='Foo')].id"
+pub trait Foo {}
+
+// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.inputs" []
+// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.kind" '"impl_trait"'
+// @count - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[*]" 1
+// @is - "$.index[*][?(@.name=='get_foo')].inner.decl.output.inner[0].trait_bound.trait.inner.id" $foo
+pub fn get_foo() -> impl Foo {
+ Fooer {}
+}
+
+struct Fooer {}
+
+impl Foo for Fooer {}
diff --git a/src/test/rustdoc-json/fns/generics.rs b/src/test/rustdoc-json/fns/generics.rs
new file mode 100644
index 000000000..e777fabaa
--- /dev/null
+++ b/src/test/rustdoc-json/fns/generics.rs
@@ -0,0 +1,26 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @set wham_id = generics.json "$.index[*][?(@.name=='Wham')].id"
+pub trait Wham {}
+
+// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
+// @count - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
+// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
+// @has - "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @is - "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
+pub fn one_generic_param_fn<T: Wham>(w: T) {}
+
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
+// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
+// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
+// @has - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.inner.id" $wham_id
+// @count - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @is - "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.inner.id" $wham_id
+pub fn one_synthetic_generic_param_fn(w: impl Wham) {}
diff --git a/src/test/rustdoc-json/fns/qualifiers.rs b/src/test/rustdoc-json/fns/qualifiers.rs
new file mode 100644
index 000000000..5cb3b43e6
--- /dev/null
+++ b/src/test/rustdoc-json/fns/qualifiers.rs
@@ -0,0 +1,33 @@
+// edition:2018
+
+// @is qualifiers.json "$.index[*][?(@.name=='nothing_fn')].inner.header.async" false
+// @is - "$.index[*][?(@.name=='nothing_fn')].inner.header.const" false
+// @is - "$.index[*][?(@.name=='nothing_fn')].inner.header.unsafe" false
+pub fn nothing_fn() {}
+
+// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.async" false
+// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.const" false
+// @is - "$.index[*][?(@.name=='unsafe_fn')].inner.header.unsafe" true
+pub unsafe fn unsafe_fn() {}
+
+// @is - "$.index[*][?(@.name=='const_fn')].inner.header.async" false
+// @is - "$.index[*][?(@.name=='const_fn')].inner.header.const" true
+// @is - "$.index[*][?(@.name=='const_fn')].inner.header.unsafe" false
+pub const fn const_fn() {}
+
+// @is - "$.index[*][?(@.name=='async_fn')].inner.header.async" true
+// @is - "$.index[*][?(@.name=='async_fn')].inner.header.const" false
+// @is - "$.index[*][?(@.name=='async_fn')].inner.header.unsafe" false
+pub async fn async_fn() {}
+
+// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.async" true
+// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.const" false
+// @is - "$.index[*][?(@.name=='async_unsafe_fn')].inner.header.unsafe" true
+pub async unsafe fn async_unsafe_fn() {}
+
+// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.async" false
+// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.const" true
+// @is - "$.index[*][?(@.name=='const_unsafe_fn')].inner.header.unsafe" true
+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/generic-associated-types/gats.rs b/src/test/rustdoc-json/generic-associated-types/gats.rs
new file mode 100644
index 000000000..368ff8d8d
--- /dev/null
+++ b/src/test/rustdoc-json/generic-associated-types/gats.rs
@@ -0,0 +1,44 @@
+// ignore-tidy-linelength
+
+#![no_core]
+#![feature(generic_associated_types, lang_items, no_core)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+pub trait Display {}
+
+// @has gats.json
+pub trait LendingIterator {
+ // @count - "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*]" 1
+ // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.params[*].name" \"\'a\"
+ // @count - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*]" 1
+ // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.type.inner" \"Self\"
+ // @is - "$.index[*][?(@.name=='LendingItem')].inner.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\"
+ // @count - "$.index[*][?(@.name=='LendingItem')].inner.bounds[*]" 1
+ type LendingItem<'a>: Display
+ where
+ Self: 'a;
+
+ // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.kind" \"qualified_path\"
+ // @count - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 1
+ // @count - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
+ // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.self_type.inner" \"Self\"
+ // @is - "$.index[*][?(@.name=='lending_next')].inner.decl.output.inner.name" \"LendingItem\"
+ fn lending_next<'a>(&'a self) -> Self::LendingItem<'a>;
+}
+
+// @has gats.json
+pub trait Iterator {
+ // @count - "$.index[*][?(@.name=='Item')].inner.generics.params[*]" 0
+ // @count - "$.index[*][?(@.name=='Item')].inner.generics.where_predicates[*]" 0
+ // @count - "$.index[*][?(@.name=='Item')].inner.bounds[*]" 1
+ type Item: Display;
+
+ // @is - "$.index[*][?(@.name=='next')].inner.decl.output.kind" \"qualified_path\"
+ // @count - "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.args[*]" 0
+ // @count - "$.index[*][?(@.name=='next')].inner.decl.output.inner.args.angle_bracketed.bindings[*]" 0
+ // @is - "$.index[*][?(@.name=='next')].inner.decl.output.inner.self_type.inner" \"Self\"
+ // @is - "$.index[*][?(@.name=='next')].inner.decl.output.inner.name" \"Item\"
+ fn next<'a>(&'a self) -> Self::Item;
+}
diff --git a/src/test/rustdoc-json/generic_impl.rs b/src/test/rustdoc-json/generic_impl.rs
new file mode 100644
index 000000000..ac68ba578
--- /dev/null
+++ b/src/test/rustdoc-json/generic_impl.rs
@@ -0,0 +1,24 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/97986>.
+
+// @has generic_impl.json
+// @has - "$.index[*][?(@.name=='f')]"
+// @has - "$.index[*][?(@.name=='AssocTy')]"
+// @has - "$.index[*][?(@.name=='AssocConst')]"
+
+pub mod m {
+ pub struct S;
+}
+
+pub trait F {
+ type AssocTy;
+ const AssocConst: usize;
+ fn f() -> m::S;
+}
+
+impl<T> F for T {
+ type AssocTy = u32;
+ const AssocConst: usize = 0;
+ fn f() -> m::S {
+ m::S
+ }
+}
diff --git a/src/test/rustdoc-json/glob_import.rs b/src/test/rustdoc-json/glob_import.rs
new file mode 100644
index 000000000..d7ac952d1
--- /dev/null
+++ b/src/test/rustdoc-json/glob_import.rs
@@ -0,0 +1,24 @@
+// This is a regression test for <https://github.com/rust-lang/rust/issues/98003>.
+
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+// @has glob_import.json
+// @has - "$.index[*][?(@.name=='glob')]"
+// @has - "$.index[*][?(@.kind=='import')].inner.name" \"*\"
+
+
+mod m1 {
+ pub fn f() {}
+}
+mod m2 {
+ pub fn f(_: u8) {}
+}
+
+pub use m1::*;
+pub use m2::*;
+
+pub mod glob {
+ pub use *;
+}
diff --git a/src/test/rustdoc-json/impls/blanket_with_local.rs b/src/test/rustdoc-json/impls/blanket_with_local.rs
new file mode 100644
index 000000000..a3d55b35f
--- /dev/null
+++ b/src/test/rustdoc-json/impls/blanket_with_local.rs
@@ -0,0 +1,18 @@
+// Test for the ICE in rust/83718
+// A blanket impl plus a local type together shouldn't result in mismatched ID issues
+
+// @has blanket_with_local.json "$.index[*][?(@.name=='Load')]"
+pub trait Load {
+ // @has - "$.index[*][?(@.name=='load')]"
+ fn load() {}
+ // @has - "$.index[*][?(@.name=='write')]"
+ fn write(self) {}
+}
+
+impl<P> Load for P {
+ fn load() {}
+ fn write(self) {}
+}
+
+// @has - "$.index[*][?(@.name=='Wrapper')]"
+pub struct Wrapper {}
diff --git a/src/test/rustdoc-json/keyword.rs b/src/test/rustdoc-json/keyword.rs
new file mode 100644
index 000000000..78a843aca
--- /dev/null
+++ b/src/test/rustdoc-json/keyword.rs
@@ -0,0 +1,21 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98002>.
+
+// Keywords should not be generated in rustdoc JSON output and this test
+// ensures it.
+
+#![feature(rustdoc_internals)]
+#![no_std]
+
+// @has keyword.json
+// @!has - "$.index[*][?(@.name=='match')]"
+// @has - "$.index[*][?(@.name=='foo')]"
+
+#[doc(keyword = "match")]
+/// this is a test!
+pub mod foo {}
+
+// @!has - "$.index[*][?(@.name=='hello')]"
+// @!has - "$.index[*][?(@.name=='bar')]"
+#[doc(keyword = "hello")]
+/// hello
+mod bar {}
diff --git a/src/test/rustdoc-json/lifetime/longest.rs b/src/test/rustdoc-json/lifetime/longest.rs
new file mode 100644
index 000000000..95b99599e
--- /dev/null
+++ b/src/test/rustdoc-json/lifetime/longest.rs
@@ -0,0 +1,33 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @is longest.json "$.index[*][?(@.name=='longest')].inner.generics.params[0].name" \"\'a\"
+// @is - "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
+// @is - "$.index[*][?(@.name=='longest')].inner.generics.params[0].kind" '{"lifetime": {"outlives": []}}'
+// @count - "$.index[*][?(@.name=='longest')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='longest')].inner.generics.where_predicates" []
+
+// @count - "$.index[*][?(@.name=='longest')].inner.decl.inputs[*]" 2
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][0]" '"l"'
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][0]" '"r"'
+
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.mutable" false
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[0][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.mutable" false
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.inputs[1][1].inner.type" '{"inner": "str", "kind": "primitive"}'
+
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.mutable" false
+// @is - "$.index[*][?(@.name=='longest')].inner.decl.output.inner.type" '{"inner": "str", "kind": "primitive"}'
+
+pub fn longest<'a>(l: &'a str, r: &'a str) -> &'a str {
+ if l.len() > r.len() { l } else { r }
+}
diff --git a/src/test/rustdoc-json/lifetime/outlives.rs b/src/test/rustdoc-json/lifetime/outlives.rs
new file mode 100644
index 000000000..096dd7f7a
--- /dev/null
+++ b/src/test/rustdoc-json/lifetime/outlives.rs
@@ -0,0 +1,23 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+// @count outlives.json "$.index[*][?(@.name=='foo')].inner.generics.params[*]" 3
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.where_predicates" []
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[0].name" \"\'a\"
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[1].name" \"\'b\"
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].name" '"T"'
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[0].kind.lifetime.outlives" []
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[1].kind.lifetime.outlives" [\"\'a\"]
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.default" null
+// @count - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='foo')].inner.generics.params[2].kind.type.bounds[0].outlives" \"\'b\"
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.mutable" false
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.kind" '"borrowed_ref"'
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.lifetime" \"\'b\"
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.mutable" false
+// @is - "$.index[*][?(@.name=='foo')].inner.decl.inputs[0][1].inner.type.inner.type" '{"inner": "T", "kind": "generic"}'
+pub fn foo<'a, 'b: 'a, T: 'b>(_: &'a &'b T) {}
diff --git a/src/test/rustdoc-json/methods/abi.rs b/src/test/rustdoc-json/methods/abi.rs
new file mode 100644
index 000000000..07b01d03b
--- /dev/null
+++ b/src/test/rustdoc-json/methods/abi.rs
@@ -0,0 +1,55 @@
+// ignore-tidy-linelength
+
+#![feature(abi_vectorcall)]
+#![feature(c_unwind)]
+#![feature(no_core)]
+#![no_core]
+
+// @has abi.json "$.index[*][?(@.name=='Foo')]"
+pub struct Foo;
+
+impl Foo {
+ // @is - "$.index[*][?(@.name=='abi_rust')].inner.header.abi" \"Rust\"
+ pub fn abi_rust() {}
+
+ // @is - "$.index[*][?(@.name=='abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+ pub extern "C" fn abi_c() {}
+
+ // @is - "$.index[*][?(@.name=='abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+ pub extern "system" fn abi_system() {}
+
+ // @is - "$.index[*][?(@.name=='abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+ pub extern "C-unwind" fn abi_c_unwind() {}
+
+ // @is - "$.index[*][?(@.name=='abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+ pub extern "system-unwind" fn abi_system_unwind() {}
+
+ // @is - "$.index[*][?(@.name=='abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+ pub extern "vectorcall" fn abi_vectorcall() {}
+
+ // @is - "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+ pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {}
+}
+
+pub trait Bar {
+ // @is - "$.index[*][?(@.name=='trait_abi_rust')].inner.header.abi" \"Rust\"
+ fn trait_abi_rust() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_c')].inner.header.abi" '{"C": {"unwind": false}}'
+ extern "C" fn trait_abi_c() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_system')].inner.header.abi" '{"System": {"unwind": false}}'
+ extern "system" fn trait_abi_system() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.header.abi" '{"C": {"unwind": true}}'
+ extern "C-unwind" fn trait_abi_c_unwind() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.header.abi" '{"System": {"unwind": true}}'
+ extern "system-unwind" fn trait_abi_system_unwind() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.header.abi.Other" '"\"vectorcall\""'
+ extern "vectorcall" fn trait_abi_vectorcall() {}
+
+ // @is - "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.header.abi.Other" '"\"vectorcall-unwind\""'
+ extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {}
+}
diff --git a/src/test/rustdoc-json/methods/qualifiers.rs b/src/test/rustdoc-json/methods/qualifiers.rs
new file mode 100644
index 000000000..af36d36b6
--- /dev/null
+++ b/src/test/rustdoc-json/methods/qualifiers.rs
@@ -0,0 +1,37 @@
+// edition:2018
+
+pub struct Foo;
+
+impl Foo {
+ // @is qualifiers.json "$.index[*][?(@.name=='const_meth')].inner.header.async" false
+ // @is - "$.index[*][?(@.name=='const_meth')].inner.header.const" true
+ // @is - "$.index[*][?(@.name=='const_meth')].inner.header.unsafe" false
+ pub const fn const_meth() {}
+
+ // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.async" false
+ // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.const" false
+ // @is - "$.index[*][?(@.name=='nothing_meth')].inner.header.unsafe" false
+ pub fn nothing_meth() {}
+
+ // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.async" false
+ // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.const" false
+ // @is - "$.index[*][?(@.name=='unsafe_meth')].inner.header.unsafe" true
+ pub unsafe fn unsafe_meth() {}
+
+ // @is - "$.index[*][?(@.name=='async_meth')].inner.header.async" true
+ // @is - "$.index[*][?(@.name=='async_meth')].inner.header.const" false
+ // @is - "$.index[*][?(@.name=='async_meth')].inner.header.unsafe" false
+ pub async fn async_meth() {}
+
+ // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.async" true
+ // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.const" false
+ // @is - "$.index[*][?(@.name=='async_unsafe_meth')].inner.header.unsafe" true
+ pub async unsafe fn async_unsafe_meth() {}
+
+ // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.async" false
+ // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.const" true
+ // @is - "$.index[*][?(@.name=='const_unsafe_meth')].inner.header.unsafe" true
+ pub const unsafe fn const_unsafe_meth() {}
+
+ // It's impossible for a method to be both const and async, so no test for that
+}
diff --git a/src/test/rustdoc-json/nested.rs b/src/test/rustdoc-json/nested.rs
new file mode 100644
index 000000000..b0e717d8a
--- /dev/null
+++ b/src/test/rustdoc-json/nested.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// compile-flags: --crate-version 1.0.0
+
+// @is nested.json "$.crate_version" \"1.0.0\"
+// @is - "$.index[*][?(@.name=='nested')].kind" \"module\"
+// @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true
+// @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1
+
+// @is nested.json "$.index[*][?(@.name=='l1')].kind" \"module\"
+// @is - "$.index[*][?(@.name=='l1')].inner.is_crate" false
+// @count - "$.index[*][?(@.name=='l1')].inner.items[*]" 2
+pub mod l1 {
+
+ // @is nested.json "$.index[*][?(@.name=='l3')].kind" \"module\"
+ // @is - "$.index[*][?(@.name=='l3')].inner.is_crate" false
+ // @count - "$.index[*][?(@.name=='l3')].inner.items[*]" 1
+ // @set l3_id = - "$.index[*][?(@.name=='l3')].id"
+ // @has - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id
+ pub mod l3 {
+
+ // @is nested.json "$.index[*][?(@.name=='L4')].kind" \"struct\"
+ // @is - "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
+ // @set l4_id = - "$.index[*][?(@.name=='L4')].id"
+ // @has - "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
+ pub struct L4;
+ }
+ // @is nested.json "$.index[*][?(@.inner.source=='l3::L4')].kind" \"import\"
+ // @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.glob" false
+ pub use l3::L4;
+}
diff --git a/src/test/rustdoc-json/output_generics.rs b/src/test/rustdoc-json/output_generics.rs
new file mode 100644
index 000000000..d80656c7f
--- /dev/null
+++ b/src/test/rustdoc-json/output_generics.rs
@@ -0,0 +1,38 @@
+// compile-flags: --document-private-items --document-hidden-items
+
+// This is a regression test for #98009.
+
+// @has output_generics.json
+// @has - "$.index[*][?(@.name=='this_compiles')]"
+// @has - "$.index[*][?(@.name=='this_does_not')]"
+// @has - "$.index[*][?(@.name=='Events')]"
+// @has - "$.index[*][?(@.name=='Other')]"
+// @has - "$.index[*][?(@.name=='Trait')]"
+
+struct Events<R>(R);
+
+struct Other;
+
+pub trait Trait<T> {
+ fn handle(value: T) -> Self;
+}
+
+impl<T, U> Trait<U> for T where T: From<U> {
+ fn handle(_: U) -> Self { unimplemented!() }
+}
+
+impl<'a, R> Trait<&'a mut Events<R>> for Other {
+ fn handle(_: &'a mut Events<R>) -> Self { unimplemented!() }
+}
+
+fn this_compiles<'a, R>(value: &'a mut Events<R>) {
+ for _ in 0..3 {
+ Other::handle(&mut *value);
+ }
+}
+
+fn this_does_not<'a, R>(value: &'a mut Events<R>) {
+ for _ in 0..3 {
+ Other::handle(value);
+ }
+}
diff --git a/src/test/rustdoc-json/primitive.rs b/src/test/rustdoc-json/primitive.rs
new file mode 100644
index 000000000..b84c2f7c6
--- /dev/null
+++ b/src/test/rustdoc-json/primitive.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+#![feature(rustdoc_internals)]
+
+#[doc(primitive = "usize")]
+mod usize {}
+
+// @set local_crate_id = primitive.json "$.index[*][?(@.name=='primitive')].crate_id"
+
+// @has - "$.index[*][?(@.name=='log10')]"
+// @!is - "$.index[*][?(@.name=='log10')].crate_id" $local_crate_id
+// @has - "$.index[*][?(@.name=='checked_add')]"
+// @!is - "$.index[*][?(@.name=='checked_add')]" $local_crate_id
+// @!has - "$.index[*][?(@.name=='is_ascii_uppercase')]"
diff --git a/src/test/rustdoc-json/primitive_overloading.rs b/src/test/rustdoc-json/primitive_overloading.rs
new file mode 100644
index 000000000..a10d5a837
--- /dev/null
+++ b/src/test/rustdoc-json/primitive_overloading.rs
@@ -0,0 +1,17 @@
+// compile-flags: --document-private-items
+
+// Regression test for <https://github.com/rust-lang/rust/issues/98006>.
+
+#![feature(rustdoc_internals)]
+#![feature(no_core)]
+
+#![no_core]
+
+// @has primitive_overloading.json
+// @has - "$.index[*][?(@.name=='usize')]"
+// @has - "$.index[*][?(@.name=='prim')]"
+
+#[doc(primitive = "usize")]
+/// This is the built-in type `usize`.
+mod prim {
+}
diff --git a/src/test/rustdoc-json/primitives.rs b/src/test/rustdoc-json/primitives.rs
new file mode 100644
index 000000000..fd04f04da
--- /dev/null
+++ b/src/test/rustdoc-json/primitives.rs
@@ -0,0 +1,22 @@
+#![feature(never_type)]
+
+// @has primitives.json "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
+pub type PrimNever = !;
+
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
+pub type PrimStr = str;
+
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
+pub type PrimBool = bool;
+
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
+pub type PrimChar = char;
+
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
+pub type PrimU8 = u8;
diff --git a/src/test/rustdoc-json/reexport/auxiliary/pub-struct.rs b/src/test/rustdoc-json/reexport/auxiliary/pub-struct.rs
new file mode 100644
index 000000000..4a835673a
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/auxiliary/pub-struct.rs
@@ -0,0 +1 @@
+pub struct Foo;
diff --git a/src/test/rustdoc-json/reexport/glob_extern.rs b/src/test/rustdoc-json/reexport/glob_extern.rs
new file mode 100644
index 000000000..ba1cfd8a0
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_extern.rs
@@ -0,0 +1,18 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
+// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+mod mod1 {
+ extern "C" {
+ // @has - "$.index[*][?(@.name=='public_fn')].id"
+ pub fn public_fn();
+ // @!has - "$.index[*][?(@.name=='private_fn')]"
+ fn private_fn();
+ }
+}
+
+// @is - "$.index[*][?(@.kind=='import')].inner.glob" true
+pub use mod1::*;
diff --git a/src/test/rustdoc-json/reexport/glob_private.rs b/src/test/rustdoc-json/reexport/glob_private.rs
new file mode 100644
index 000000000..e6a44748c
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/glob_private.rs
@@ -0,0 +1,32 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @is glob_private.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
+// @is glob_private.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+mod mod1 {
+ // @is - "$.index[*][?(@.name=='mod2')].kind" \"module\"
+ // @is - "$.index[*][?(@.name=='mod2')].inner.is_stripped" "true"
+ mod mod2 {
+ // @set m2pub_id = - "$.index[*][?(@.name=='Mod2Public')].id"
+ pub struct Mod2Public;
+
+ // @!has - "$.index[*][?(@.name=='Mod2Private')]"
+ struct Mod2Private;
+ }
+
+ // @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
+ pub use self::mod2::*;
+
+ // @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
+ pub struct Mod1Public;
+ // @!has - "$.index[*][?(@.name=='Mod1Private')]"
+ struct Mod1Private;
+}
+
+// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
+pub use mod1::*;
+
+// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
+// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod.rs b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
new file mode 100644
index 000000000..7bf10a986
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod.rs
@@ -0,0 +1,17 @@
+#![feature(no_core)]
+#![no_core]
+
+// @is in_root_and_mod.json "$.index[*][?(@.name=='foo')].kind" \"module\"
+// @is in_root_and_mod.json "$.index[*][?(@.name=='foo')].inner.is_stripped" "true"
+mod foo {
+ // @has - "$.index[*][?(@.name=='Foo')]"
+ pub struct Foo;
+}
+
+// @has - "$.index[*][?(@.kind=='import' && @.inner.source=='foo::Foo')]"
+pub use foo::Foo;
+
+pub mod bar {
+ // @has - "$.index[*][?(@.kind=='import' && @.inner.source=='crate::foo::Foo')]"
+ pub use crate::foo::Foo;
+}
diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
new file mode 100644
index 000000000..2daadf762
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
@@ -0,0 +1,20 @@
+#![feature(no_core)]
+#![no_core]
+
+pub mod foo {
+ // @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
+ // @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
+ pub struct Bar;
+}
+
+// @set root_import_id = - "$.index[*][?(@.inner.source=='foo::Bar')].id"
+// @is - "$.index[*][?(@.inner.source=='foo::Bar')].inner.id" $bar_id
+// @has - "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.items[*]" $root_import_id
+pub use foo::Bar;
+
+pub mod baz {
+ // @set baz_import_id = - "$.index[*][?(@.inner.source=='crate::foo::Bar')].id"
+ // @is - "$.index[*][?(@.inner.source=='crate::foo::Bar')].inner.id" $bar_id
+ // @has - "$.index[*][?(@.name=='baz')].inner.items[*]" $baz_import_id
+ pub use crate::foo::Bar;
+}
diff --git a/src/test/rustdoc-json/reexport/macro.rs b/src/test/rustdoc-json/reexport/macro.rs
new file mode 100644
index 000000000..b86614ffb
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/macro.rs
@@ -0,0 +1,17 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @count macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" 2
+
+// @set repro_id = macro.json "$.index[*][?(@.name=='repro')].id"
+// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id
+#[macro_export]
+macro_rules! repro {
+ () => {};
+}
+
+// @set repro2_id = macro.json "$.index[*][?(@.inner.name=='repro2')].id"
+// @has - "$.index[*][?(@.name=='macro')].inner.items[*]" $repro2_id
+pub use crate::repro as repro2;
diff --git a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
new file mode 100644
index 000000000..327b0f45f
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -0,0 +1,18 @@
+// aux-build:pub-struct.rs
+
+// Test for the ICE in rust/83057
+// Am external type re-exported with different attributes shouldn't cause an error
+
+#![no_core]
+#![feature(no_core)]
+
+extern crate pub_struct as foo;
+
+#[doc(inline)]
+pub use foo::Foo;
+
+pub mod bar {
+ pub use foo::Foo;
+}
+
+// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2
diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs
new file mode 100644
index 000000000..36d6a50d3
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/private_two_names.rs
@@ -0,0 +1,17 @@
+// Test for the ICE in rust/83720
+// A pub-in-private type re-exported under two different names shouldn't cause an error
+
+#![no_core]
+#![feature(no_core)]
+
+// @is private_two_names.json "$.index[*][?(@.name=='style')].kind" \"module\"
+// @is private_two_names.json "$.index[*][?(@.name=='style')].inner.is_stripped" "true"
+mod style {
+ // @has - "$.index[*](?(@.name=='Color'))"
+ pub struct Color;
+}
+
+// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
+pub use style::Color;
+// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
+pub use style::Color as Colour;
diff --git a/src/test/rustdoc-json/reexport/rename_private.rs b/src/test/rustdoc-json/reexport/rename_private.rs
new file mode 100644
index 000000000..2476399bd
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/rename_private.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @is rename_private.json "$.index[*][?(@.name=='inner')].kind" \"module\"
+// @is rename_private.json "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
+mod inner {
+ // @has - "$.index[*][?(@.name=='Public')]"
+ pub struct Public;
+}
+
+// @is - "$.index[*][?(@.kind=='import')].inner.name" \"NewName\"
+pub use inner::Public as NewName;
diff --git a/src/test/rustdoc-json/reexport/rename_public.rs b/src/test/rustdoc-json/reexport/rename_public.rs
new file mode 100644
index 000000000..2dd438d22
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/rename_public.rs
@@ -0,0 +1,17 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @set inner_id = rename_public.json "$.index[*][?(@.name=='inner')].id"
+// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id
+pub mod inner {
+ // @set public_id = - "$.index[*][?(@.name=='Public')].id"
+ // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+ pub struct Public;
+}
+// @set import_id = - "$.index[*][?(@.inner.name=='NewName')].id"
+// @!has - "$.index[*][?(@.inner.name=='Public')]"
+// @has - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $import_id
+// @is - "$.index[*][?(@.inner.name=='NewName')].inner.source" \"inner::Public\"
+pub use inner::Public as NewName;
diff --git a/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
new file mode 100644
index 000000000..eedddd6a7
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
@@ -0,0 +1,15 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/97432>.
+
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+// @has same_type_reexported_more_than_once.json
+// @has - "$.index[*][?(@.name=='Trait')]"
+pub use inner::Trait;
+// @has - "$.index[*].inner[?(@.name=='Reexport')].id"
+pub use inner::Trait as Reexport;
+
+mod inner {
+ pub trait Trait {}
+}
diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs
new file mode 100644
index 000000000..5ec13e403
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/simple_private.rs
@@ -0,0 +1,15 @@
+// edition:2018
+#![no_core]
+#![feature(no_core)]
+
+// @is simple_private.json "$.index[*][?(@.name=='inner')].kind" \"module\"
+// @is simple_private.json "$.index[*][?(@.name=='inner')].inner.is_stripped" "true"
+mod inner {
+ // @set pub_id = - "$.index[*][?(@.name=='Public')].id"
+ pub struct Public;
+}
+
+// @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
+pub use inner::Public;
+
+// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
diff --git a/src/test/rustdoc-json/reexport/simple_public.rs b/src/test/rustdoc-json/reexport/simple_public.rs
new file mode 100644
index 000000000..2e4de301f
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/simple_public.rs
@@ -0,0 +1,18 @@
+// edition:2018
+
+#![no_core]
+#![feature(no_core)]
+
+// @set inner_id = simple_public.json "$.index[*][?(@.name=='inner')].id"
+// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $inner_id
+pub mod inner {
+
+ // @set public_id = - "$.index[*][?(@.name=='Public')].id"
+ // @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $public_id
+ pub struct Public;
+}
+
+// @set import_id = - "$.index[*][?(@.inner.name=='Public')].id"
+// @has - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id
+// @is - "$.index[*][?(@.inner.name=='Public')].inner.source" \"inner::Public\"
+pub use inner::Public;
diff --git a/src/test/rustdoc-json/return_private.rs b/src/test/rustdoc-json/return_private.rs
new file mode 100644
index 000000000..6b324d009
--- /dev/null
+++ b/src/test/rustdoc-json/return_private.rs
@@ -0,0 +1,15 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/96161>.
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![no_core]
+
+mod secret {
+ pub struct Secret;
+}
+
+// @is return_private.json "$.index[*][?(@.name=='get_secret')].kind" \"function\"
+// @is return_private.json "$.index[*][?(@.name=='get_secret')].inner.decl.output.inner.name" \"secret::Secret\"
+pub fn get_secret() -> secret::Secret {
+ secret::Secret
+}
diff --git a/src/test/rustdoc-json/stripped_modules.rs b/src/test/rustdoc-json/stripped_modules.rs
new file mode 100644
index 000000000..91f9f02ad
--- /dev/null
+++ b/src/test/rustdoc-json/stripped_modules.rs
@@ -0,0 +1,21 @@
+#![no_core]
+#![feature(no_core)]
+
+// @!has stripped_modules.json "$.index[*][?(@.name=='no_pub_inner')]"
+mod no_pub_inner {
+ fn priv_inner() {}
+}
+
+// @!has - "$.index[*][?(@.name=='pub_inner_unreachable')]"
+mod pub_inner_unreachable {
+ // @!has - "$.index[*][?(@.name=='pub_inner_1')]"
+ pub fn pub_inner_1() {}
+}
+
+// @has - "$.index[*][?(@.name=='pub_inner_reachable')]"
+mod pub_inner_reachable {
+ // @has - "$.index[*][?(@.name=='pub_inner_2')]"
+ pub fn pub_inner_2() {}
+}
+
+pub use pub_inner_reachable::pub_inner_2;
diff --git a/src/test/rustdoc-json/structs/plain_empty.rs b/src/test/rustdoc-json/structs/plain_empty.rs
new file mode 100644
index 000000000..a251caf4b
--- /dev/null
+++ b/src/test/rustdoc-json/structs/plain_empty.rs
@@ -0,0 +1,6 @@
+// @has plain_empty.json "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
+// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.struct_type" \"plain\"
+// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.fields_stripped" false
+// @has - "$.index[*][?(@.name=='PlainEmpty')].inner.fields" []
+pub struct PlainEmpty {}
diff --git a/src/test/rustdoc-json/structs/tuple.rs b/src/test/rustdoc-json/structs/tuple.rs
new file mode 100644
index 000000000..4e510b398
--- /dev/null
+++ b/src/test/rustdoc-json/structs/tuple.rs
@@ -0,0 +1,5 @@
+// @has tuple.json "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
+// @has - "$.index[*][?(@.name=='Tuple')].inner.struct_type" \"tuple\"
+// @has - "$.index[*][?(@.name=='Tuple')].inner.fields_stripped" true
+pub struct Tuple(u32, String);
diff --git a/src/test/rustdoc-json/structs/unit.rs b/src/test/rustdoc-json/structs/unit.rs
new file mode 100644
index 000000000..559d3068d
--- /dev/null
+++ b/src/test/rustdoc-json/structs/unit.rs
@@ -0,0 +1,5 @@
+// @has unit.json "$.index[*][?(@.name=='Unit')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='Unit')].kind" \"struct\"
+// @has - "$.index[*][?(@.name=='Unit')].inner.struct_type" \"unit\"
+// @has - "$.index[*][?(@.name=='Unit')].inner.fields" []
+pub struct Unit;
diff --git a/src/test/rustdoc-json/structs/with_generics.rs b/src/test/rustdoc-json/structs/with_generics.rs
new file mode 100644
index 000000000..65cfe7eff
--- /dev/null
+++ b/src/test/rustdoc-json/structs/with_generics.rs
@@ -0,0 +1,14 @@
+use std::collections::HashMap;
+
+// @has with_generics.json "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.struct_type" \"plain\"
+// @has - "$.index[*][?(@.name=='WithGenerics')].inner.fields_stripped" true
+pub struct WithGenerics<T, U> {
+ stuff: Vec<T>,
+ things: HashMap<U, U>,
+}
diff --git a/src/test/rustdoc-json/structs/with_primitives.rs b/src/test/rustdoc-json/structs/with_primitives.rs
new file mode 100644
index 000000000..9e64317ec
--- /dev/null
+++ b/src/test/rustdoc-json/structs/with_primitives.rs
@@ -0,0 +1,10 @@
+// @has with_primitives.json "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
+// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
+// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
+// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.struct_type" \"plain\"
+// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.fields_stripped" true
+pub struct WithPrimitives<'a> {
+ num: u32,
+ s: &'a str,
+}
diff --git a/src/test/rustdoc-json/traits/has_body.rs b/src/test/rustdoc-json/traits/has_body.rs
new file mode 100644
index 000000000..44dacb1ee
--- /dev/null
+++ b/src/test/rustdoc-json/traits/has_body.rs
@@ -0,0 +1,21 @@
+// @has has_body.json "$.index[*][?(@.name=='Foo')]"
+pub trait Foo {
+ // @has - "$.index[*][?(@.name=='no_self')].inner.has_body" false
+ fn no_self();
+ // @has - "$.index[*][?(@.name=='move_self')].inner.has_body" false
+ fn move_self(self);
+ // @has - "$.index[*][?(@.name=='ref_self')].inner.has_body" false
+ fn ref_self(&self);
+
+ // @has - "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
+ fn no_self_def() {}
+ // @has - "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
+ fn move_self_def(self) {}
+ // @has - "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
+ fn ref_self_def(&self) {}
+}
+
+pub trait Bar: Clone {
+ // @has - "$.index[*][?(@.name=='method')].inner.has_body" false
+ fn method(&self, param: usize);
+}
diff --git a/src/test/rustdoc-json/traits/implementors.rs b/src/test/rustdoc-json/traits/implementors.rs
new file mode 100644
index 000000000..f7f03d987
--- /dev/null
+++ b/src/test/rustdoc-json/traits/implementors.rs
@@ -0,0 +1,19 @@
+#![feature(no_core)]
+#![no_core]
+
+// @set wham = implementors.json "$.index[*][?(@.name=='Wham')].id"
+// @count - "$.index[*][?(@.name=='Wham')].inner.implementations[*]" 1
+// @set gmWham = - "$.index[*][?(@.name=='Wham')].inner.implementations[0]"
+pub trait Wham {}
+
+// @count - "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[*]" 1
+// @is - "$.index[*][?(@.name=='GeorgeMichael')].inner.impls[0]" $gmWham
+// @set gm = - "$.index[*][?(@.name=='Wham')].id"
+
+// jsonpath_lib isnt expressive enough (for now) to get the "impl" item, so we
+// just check it isn't pointing to the type, but when you port to jsondocck-ng
+// check what the impl item is
+// @!is - "$.index[*][?(@.name=='Wham')].inner.implementations[0]" $gm
+pub struct GeorgeMichael {}
+
+impl Wham for GeorgeMichael {}
diff --git a/src/test/rustdoc-json/traits/supertrait.rs b/src/test/rustdoc-json/traits/supertrait.rs
new file mode 100644
index 000000000..486a8e713
--- /dev/null
+++ b/src/test/rustdoc-json/traits/supertrait.rs
@@ -0,0 +1,26 @@
+// ignore-tidy-linelength
+
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+// @set loud_id = supertrait.json "$.index[*][?(@.name=='Loud')].id"
+pub trait Loud {}
+
+// @set very_loud_id = - "$.index[*][?(@.name=='VeryLoud')].id"
+// @count - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[*]" 1
+// @is - "$.index[*][?(@.name=='VeryLoud')].inner.bounds[0].trait_bound.trait.inner.id" $loud_id
+pub trait VeryLoud: Loud {}
+
+// @set sounds_good_id = - "$.index[*][?(@.name=='SoundsGood')].id"
+pub trait SoundsGood {}
+
+// @count - "$.index[*][?(@.name=='MetalBand')].inner.bounds[*]" 2
+// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[0].trait_bound.trait.inner.id" $very_loud_id
+// @is - "$.index[*][?(@.name=='MetalBand')].inner.bounds[1].trait_bound.trait.inner.id" $sounds_good_id
+pub trait MetalBand: VeryLoud + SoundsGood {}
+
+// @count - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[*]" 2
+// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[1].trait_bound.trait.inner.id" $very_loud_id
+// @is - "$.index[*][?(@.name=='DnabLatem')].inner.bounds[0].trait_bound.trait.inner.id" $sounds_good_id
+pub trait DnabLatem: SoundsGood + VeryLoud {}
diff --git a/src/test/rustdoc-json/type/dyn.rs b/src/test/rustdoc-json/type/dyn.rs
new file mode 100644
index 000000000..f53dc03f4
--- /dev/null
+++ b/src/test/rustdoc-json/type/dyn.rs
@@ -0,0 +1,21 @@
+// ignore-tidy-linelength
+
+// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items" 1
+// @set sync_int_gen = - "$.index[*][?(@.name=='SyncIntGen')].id"
+// @is - "$.index[*][?(@.name=='dyn')].inner.items[0]" $sync_int_gen
+
+// @is - "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}'
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.kind" \"resolved_path\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" []
+// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.name" \"Fn\"
+// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[*]" 3
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[0].trait_bound.trait.inner.name" \"Send\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[1].trait_bound.trait.inner.name" \"Sync\"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[2]" "{\"outlives\": \"'static\"}"
+// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}'
+pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>;
diff --git a/src/test/rustdoc-json/type/fn_lifetime.rs b/src/test/rustdoc-json/type/fn_lifetime.rs
new file mode 100644
index 000000000..e0d1e9649
--- /dev/null
+++ b/src/test/rustdoc-json/type/fn_lifetime.rs
@@ -0,0 +1,28 @@
+// ignore-tidy-linelength
+
+// @is fn_lifetime.json "$.index[*][?(@.name=='GenericFn')].kind" \"typedef\"
+
+// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*]" 1
+// @is - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].name" \"\'a\"
+// @has - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime"
+// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.params[*].kind.lifetime.outlives[*]" 0
+// @count - "$.index[*][?(@.name=='GenericFn')].inner.generics.where_predicates[*]" 0
+// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.kind" \"function_pointer\"
+// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.generic_params[*]" 0
+// @count - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='GenericFn')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+
+pub type GenericFn<'a> = fn(&'a i32) -> &'a i32;
+
+// @is fn_lifetime.json "$.index[*][?(@.name=='ForAll')].kind" \"typedef\"
+// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.params[*]" 0
+// @count - "$.index[*][?(@.name=='ForAll')].inner.generics.where_predicates[*]" 0
+// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*]" 1
+// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].name" \"\'a\"
+// @has - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime"
+// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.generic_params[*].kind.lifetime.outlives[*]" 0
+// @count - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*]" 1
+// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.inputs[*][1].inner.lifetime" \"\'a\"
+// @is - "$.index[*][?(@.name=='ForAll')].inner.type.inner.decl.output.inner.lifetime" \"\'a\"
+pub type ForAll = for<'a> fn(&'a i32) -> &'a i32;
diff --git a/src/test/rustdoc-json/type/generic_default.rs b/src/test/rustdoc-json/type/generic_default.rs
new file mode 100644
index 000000000..b6bb6dcc5
--- /dev/null
+++ b/src/test/rustdoc-json/type/generic_default.rs
@@ -0,0 +1,33 @@
+// ignore-tidy-linelength
+
+// @set result = generic_default.json "$.index[*][?(@.name=='Result')].id"
+pub enum Result<T, E> {
+ Ok(T),
+ Err(E),
+}
+
+// @set my_error = - "$.index[*][?(@.name=='MyError')].id"
+pub struct MyError {}
+
+// @is - "$.index[*][?(@.name=='MyResult')].kind" \"typedef\"
+// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.where_predicates[*]" 0
+// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[*]" 2
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].name" \"T\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].name" \"E\"
+// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type"
+// @has - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type"
+// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.bounds[*]" 0
+// @count - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.bounds[*]" 0
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[0].kind.type.default" null
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.kind" \"resolved_path\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.id" $my_error
+// @is - "$.index[*][?(@.name=='MyResult')].inner.generics.params[1].kind.type.default.inner.name" \"MyError\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.kind" \"resolved_path\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.id" $result
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.name" \"Result\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.bindings" []
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"generic\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.kind" \"generic\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[0].type.inner" \"T\"
+// @is - "$.index[*][?(@.name=='MyResult')].inner.type.inner.args.angle_bracketed.args[1].type.inner" \"E\"
+pub type MyResult<T, E = MyError> = Result<T, E>;
diff --git a/src/test/rustdoc-json/unions/impl.rs b/src/test/rustdoc-json/unions/impl.rs
new file mode 100644
index 000000000..0388b4a8c
--- /dev/null
+++ b/src/test/rustdoc-json/unions/impl.rs
@@ -0,0 +1,15 @@
+#![no_std]
+
+// @has impl.json "$.index[*][?(@.name=='Ux')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='Ux')].kind" \"union\"
+pub union Ux {
+ a: u32,
+ b: u64
+}
+
+// @has - "$.index[*][?(@.name=='Num')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='Num')].kind" \"trait\"
+pub trait Num {}
+
+// @count - "$.index[*][?(@.name=='Ux')].inner.impls" 1
+impl Num for Ux {}
diff --git a/src/test/rustdoc-json/unions/union.rs b/src/test/rustdoc-json/unions/union.rs
new file mode 100644
index 000000000..ac2eb7977
--- /dev/null
+++ b/src/test/rustdoc-json/unions/union.rs
@@ -0,0 +1,7 @@
+// @has union.json "$.index[*][?(@.name=='Union')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='Union')].kind" \"union\"
+// @!has - "$.index[*][?(@.name=='Union')].inner.struct_type"
+pub union Union {
+ int: i32,
+ float: f32,
+}