about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/rustdoc-json/nested.rs13
-rw-r--r--src/test/rustdoc-json/reexport/glob_extern.rs9
-rw-r--r--src/test/rustdoc-json/reexport/glob_private.rs9
-rw-r--r--src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs4
-rw-r--r--src/test/rustdoc-json/reexport/macro.rs6
-rw-r--r--src/test/rustdoc-json/reexport/private_twice_one_inline.rs18
-rw-r--r--src/test/rustdoc-json/reexport/private_two_names.rs14
-rw-r--r--src/test/rustdoc-json/reexport/rename_public.rs6
-rw-r--r--src/test/rustdoc-json/reexport/same_type_reexported_more_than_once.rs16
-rw-r--r--src/test/rustdoc-json/reexport/simple_private.rs4
-rw-r--r--src/test/rustdoc-json/reexport/simple_public.rs6
-rw-r--r--src/test/rustdoc-json/type/fn_lifetime.rs3
-rw-r--r--src/tools/jsondocck/src/main.rs42
13 files changed, 111 insertions, 39 deletions
diff --git a/src/test/rustdoc-json/nested.rs b/src/test/rustdoc-json/nested.rs
index b0e717d8a86..9ff1f60c0d5 100644
--- a/src/test/rustdoc-json/nested.rs
+++ b/src/test/rustdoc-json/nested.rs
@@ -4,27 +4,28 @@
 // @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
+
+// @set l1_id = - "$.index[*][?(@.name=='l1')].id"
+// @ismany - "$.index[*][?(@.name=='nested')].inner.items[*]" $l1_id
 
 // @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
+        // @ismany - "$.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
+    // @is - "$.index[*][?(@.inner.source=='l3::L4')].inner.id" $l4_id
+    // @set l4_use_id = - "$.index[*][?(@.inner.source=='l3::L4')].id"
     pub use l3::L4;
 }
+// @ismany - "$.index[*][?(@.name=='l1')].inner.items[*]" $l3_id $l4_use_id
diff --git a/src/test/rustdoc-json/reexport/glob_extern.rs b/src/test/rustdoc-json/reexport/glob_extern.rs
index ba1cfd8a0b5..4fe25904423 100644
--- a/src/test/rustdoc-json/reexport/glob_extern.rs
+++ b/src/test/rustdoc-json/reexport/glob_extern.rs
@@ -4,15 +4,20 @@
 #![feature(no_core)]
 
 // @is glob_extern.json "$.index[*][?(@.name=='mod1')].kind" \"module\"
-// @is glob_extern.json "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
+// @is - "$.index[*][?(@.name=='mod1')].inner.is_stripped" "true"
 mod mod1 {
     extern "C" {
-        // @has - "$.index[*][?(@.name=='public_fn')].id"
+        // @set public_fn_id = - "$.index[*][?(@.name=='public_fn')].id"
         pub fn public_fn();
         // @!has - "$.index[*][?(@.name=='private_fn')]"
         fn private_fn();
     }
+    // @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $public_fn_id
+    // @set mod1_id = - "$.index[*][?(@.name=='mod1')].id"
 }
 
 // @is - "$.index[*][?(@.kind=='import')].inner.glob" true
+// @is - "$.index[*][?(@.kind=='import')].inner.id" $mod1_id
+// @set use_id = - "$.index[*][?(@.kind=='import')].id"
+// @ismany - "$.index[*][?(@.name=='glob_extern')].inner.items[*]" $use_id
 pub use mod1::*;
diff --git a/src/test/rustdoc-json/reexport/glob_private.rs b/src/test/rustdoc-json/reexport/glob_private.rs
index e6a44748c25..04460a817f1 100644
--- a/src/test/rustdoc-json/reexport/glob_private.rs
+++ b/src/test/rustdoc-json/reexport/glob_private.rs
@@ -16,7 +16,7 @@ mod mod1 {
         struct Mod2Private;
     }
 
-    // @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')]"
+    // @set mod2_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod2')].id"
     pub use self::mod2::*;
 
     // @set m1pub_id = - "$.index[*][?(@.name=='Mod1Public')].id"
@@ -25,8 +25,9 @@ mod mod1 {
     struct Mod1Private;
 }
 
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')]"
+// @set mod1_use_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='mod1')].id"
 pub use mod1::*;
 
-// @has - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
-// @has - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id
+// @ismany - "$.index[*][?(@.name=='mod2')].inner.items[*]" $m2pub_id
+// @ismany - "$.index[*][?(@.name=='mod1')].inner.items[*]" $m1pub_id $mod2_use_id
+// @ismany - "$.index[*][?(@.name=='glob_private')].inner.items[*]" $mod1_use_id
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
index 2daadf7620c..09302ee3acb 100644
--- a/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
+++ b/src/test/rustdoc-json/reexport/in_root_and_mod_pub.rs
@@ -3,7 +3,7 @@
 
 pub mod foo {
     // @set bar_id = in_root_and_mod_pub.json "$.index[*][?(@.name=='Bar')].id"
-    // @has - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
+    // @ismany - "$.index[*][?(@.name=='foo')].inner.items[*]" $bar_id
     pub struct Bar;
 }
 
@@ -15,6 +15,6 @@ 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
+    // @ismany - "$.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
index b86614ffbad..0959736f309 100644
--- a/src/test/rustdoc-json/reexport/macro.rs
+++ b/src/test/rustdoc-json/reexport/macro.rs
@@ -3,15 +3,13 @@
 #![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;
+
+// @ismany macro.json "$.index[*][?(@.name=='macro')].inner.items[*]" $repro_id $repro2_id
diff --git a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
index 327b0f45fdd..a76d352b28b 100644
--- a/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
+++ b/src/test/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -1,18 +1,28 @@
 // aux-build:pub-struct.rs
+// ignore-tidy-linelength
 
-// Test for the ICE in rust/83057
-// Am external type re-exported with different attributes shouldn't cause an error
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83057
+// An 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)]
+
+// @set crate_use_id = private_twice_one_inline.json "$.index[*][?(@.docs=='Hack A')].id"
+// @set foo_id = - "$.index[*][?(@.docs=='Hack A')].inner.id"
+/// Hack A
 pub use foo::Foo;
 
+// @set bar_id = - "$.index[*][?(@.name=='bar')].id"
 pub mod bar {
+    // @is - "$.index[*][?(@.docs=='Hack B')].inner.id" $foo_id
+    // @set bar_use_id = - "$.index[*][?(@.docs=='Hack B')].id"
+    // @ismany - "$.index[*][?(@.name=='bar')].inner.items[*]" $bar_use_id
+    /// Hack B
     pub use foo::Foo;
 }
 
-// @count private_twice_one_inline.json "$.index[*][?(@.kind=='import')]" 2
+// @ismany - "$.index[*][?(@.kind=='import')].id" $crate_use_id $bar_use_id
+// @ismany - "$.index[*][?(@.name=='private_twice_one_inline')].inner.items[*]" $bar_id $crate_use_id
diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs
index 36d6a50d385..cd8212cf344 100644
--- a/src/test/rustdoc-json/reexport/private_two_names.rs
+++ b/src/test/rustdoc-json/reexport/private_two_names.rs
@@ -1,4 +1,6 @@
-// Test for the ICE in rust/83720
+// ignore-tidy-linelength
+
+// Test for the ICE in https://github.com/rust-lang/rust/issues/83720
 // A pub-in-private type re-exported under two different names shouldn't cause an error
 
 #![no_core]
@@ -7,11 +9,15 @@
 // @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'))"
+    // @set color_struct_id = - "$.index[*][?(@.kind=='struct' && @.name=='Color')].id"
     pub struct Color;
 }
 
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')]"
+// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].inner.id" $color_struct_id
+// @set color_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Color')].id"
 pub use style::Color;
-// @has - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')]"
+// @is - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].inner.id" $color_struct_id
+// @set colour_export_id = - "$.index[*][?(@.kind=='import' && @.inner.name=='Colour')].id"
 pub use style::Color as Colour;
+
+// @ismany - "$.index[*][?(@.name=='private_two_names')].inner.items[*]" $color_export_id $colour_export_id
diff --git a/src/test/rustdoc-json/reexport/rename_public.rs b/src/test/rustdoc-json/reexport/rename_public.rs
index 2dd438d2230..d41556974b4 100644
--- a/src/test/rustdoc-json/reexport/rename_public.rs
+++ b/src/test/rustdoc-json/reexport/rename_public.rs
@@ -4,14 +4,14 @@
 #![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
+    // @ismany - "$.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;
+
+// @ismany - "$.index[*][?(@.name=='rename_public')].inner.items[*]" $inner_id $import_id
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
index eedddd6a7bb..1d76c7e139b 100644
--- 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
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 // Regression test for <https://github.com/rust-lang/rust/issues/97432>.
 
 #![feature(no_core)]
@@ -5,11 +7,17 @@
 #![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 {
+    // @set trait_id = - "$.index[*][?(@.name=='Trait')].id"
     pub trait Trait {}
 }
+
+// @set export_id = - "$.index[*][?(@.inner.name=='Trait')].id"
+// @is - "$.index[*][?(@.inner.name=='Trait')].inner.id" $trait_id
+pub use inner::Trait;
+// @set reexport_id = - "$.index[*][?(@.inner.name=='Reexport')].id"
+// @is - "$.index[*][?(@.inner.name=='Reexport')].inner.id" $trait_id
+pub use inner::Trait as Reexport;
+
+// @ismany - "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.items[*]" $reexport_id $export_id
diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs
index 5ec13e403ae..55523bcd1de 100644
--- a/src/test/rustdoc-json/reexport/simple_private.rs
+++ b/src/test/rustdoc-json/reexport/simple_private.rs
@@ -10,6 +10,8 @@ mod inner {
 }
 
 // @is - "$.index[*][?(@.kind=='import')].inner.name" \"Public\"
+// @set use_id = - "$.index[*][?(@.kind=='import')].id"
 pub use inner::Public;
 
-// @has - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
+// @ismany - "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id
+// @ismany - "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id
diff --git a/src/test/rustdoc-json/reexport/simple_public.rs b/src/test/rustdoc-json/reexport/simple_public.rs
index 2e4de301f6f..a3156a2b33a 100644
--- a/src/test/rustdoc-json/reexport/simple_public.rs
+++ b/src/test/rustdoc-json/reexport/simple_public.rs
@@ -4,15 +4,15 @@
 #![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
+    // @ismany - "$.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;
+
+// @ismany - "$.index[*][?(@.name=='simple_public')].inner.items[*]" $import_id $inner_id
diff --git a/src/test/rustdoc-json/type/fn_lifetime.rs b/src/test/rustdoc-json/type/fn_lifetime.rs
index e0d1e9649a0..fd49a0890c0 100644
--- a/src/test/rustdoc-json/type/fn_lifetime.rs
+++ b/src/test/rustdoc-json/type/fn_lifetime.rs
@@ -2,8 +2,7 @@
 
 // @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\"
+// @ismany    - "$.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
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index c4462466646..022f7eb8e02 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -50,6 +50,7 @@ pub enum CommandKind {
     Has,
     Count,
     Is,
+    IsMany,
     Set,
 }
 
@@ -57,6 +58,7 @@ impl CommandKind {
     fn validate(&self, args: &[String], command_num: usize, lineno: usize) -> bool {
         let count = match self {
             CommandKind::Has => (1..=3).contains(&args.len()),
+            CommandKind::IsMany => args.len() >= 3,
             CommandKind::Count | CommandKind::Is => 3 == args.len(),
             CommandKind::Set => 4 == args.len(),
         };
@@ -89,6 +91,7 @@ impl fmt::Display for CommandKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let text = match self {
             CommandKind::Has => "has",
+            CommandKind::IsMany => "ismany",
             CommandKind::Count => "count",
             CommandKind::Is => "is",
             CommandKind::Set => "set",
@@ -137,6 +140,7 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
             "has" => CommandKind::Has,
             "count" => CommandKind::Count,
             "is" => CommandKind::Is,
+            "ismany" => CommandKind::IsMany,
             "set" => CommandKind::Set,
             _ => {
                 print_err(&format!("Unrecognized command name `@{}`", cmd), lineno);
@@ -227,6 +231,44 @@ fn check_command(command: Command, cache: &mut Cache) -> Result<(), CkError> {
                 _ => unreachable!(),
             }
         }
+        CommandKind::IsMany => {
+            // @ismany <path> <jsonpath> <value>...
+            let (path, query, values) = if let [path, query, values @ ..] = &command.args[..] {
+                (path, query, values)
+            } else {
+                unreachable!("Checked in CommandKind::validate")
+            };
+            let val = cache.get_value(path)?;
+            let got_values = select(&val, &query).unwrap();
+            assert!(!command.negated, "`@!ismany` is not supported");
+
+            // Serde json doesn't implement Ord or Hash for Value, so we must
+            // use a Vec here. While in theory that makes setwize equality
+            // O(n^2), in practice n will never be large enought to matter.
+            let expected_values =
+                values.iter().map(|v| string_to_value(v, cache)).collect::<Vec<_>>();
+            if expected_values.len() != got_values.len() {
+                return Err(CkError::FailedCheck(
+                    format!(
+                        "Expected {} values, but `{}` matched to {} values ({:?})",
+                        expected_values.len(),
+                        query,
+                        got_values.len(),
+                        got_values
+                    ),
+                    command,
+                ));
+            };
+            for got_value in got_values {
+                if !expected_values.iter().any(|exp| &**exp == got_value) {
+                    return Err(CkError::FailedCheck(
+                        format!("`{}` has match {:?}, which was not expected", query, got_value),
+                        command,
+                    ));
+                }
+            }
+            true
+        }
         CommandKind::Count => {
             // @count <path> <jsonpath> <count> = Check that the jsonpath matches exactly [count] times
             assert_eq!(command.args.len(), 3);