about summary refs log tree commit diff
path: root/tests/rustdoc-js
diff options
context:
space:
mode:
Diffstat (limited to 'tests/rustdoc-js')
-rw-r--r--tests/rustdoc-js/assoc-type-backtrack.js163
-rw-r--r--tests/rustdoc-js/assoc-type-backtrack.rs38
-rw-r--r--tests/rustdoc-js/assoc-type-loop.js9
-rw-r--r--tests/rustdoc-js/assoc-type-loop.rs35
-rw-r--r--tests/rustdoc-js/assoc-type.js56
-rw-r--r--tests/rustdoc-js/assoc-type.rs12
-rw-r--r--tests/rustdoc-js/big-result.js39
-rw-r--r--tests/rustdoc-js/big-result.rs61
-rw-r--r--tests/rustdoc-js/enum-variant-not-type.js70
-rw-r--r--tests/rustdoc-js/enum-variant-not-type.rs14
-rw-r--r--tests/rustdoc-js/exact-match.js1
-rw-r--r--tests/rustdoc-js/full-path-function.js4
-rw-r--r--tests/rustdoc-js/gat.js57
-rw-r--r--tests/rustdoc-js/gat.rs8
-rw-r--r--tests/rustdoc-js/generics.js1
-rw-r--r--tests/rustdoc-js/generics2.js22
-rw-r--r--tests/rustdoc-js/generics2.rs13
-rw-r--r--tests/rustdoc-js/impl-trait.js2
-rw-r--r--tests/rustdoc-js/module-substring.js22
-rw-r--r--tests/rustdoc-js/never-search.js10
-rw-r--r--tests/rustdoc-js/path-maxeditdistance.js35
-rw-r--r--tests/rustdoc-js/path-maxeditdistance.rs3
-rw-r--r--tests/rustdoc-js/path-ordering.js8
-rw-r--r--tests/rustdoc-js/path-ordering.rs6
-rw-r--r--tests/rustdoc-js/substring.js22
-rw-r--r--tests/rustdoc-js/substring.rs2
-rw-r--r--tests/rustdoc-js/trait-methods.js12
-rw-r--r--tests/rustdoc-js/trait-methods.rs4
-rw-r--r--tests/rustdoc-js/tuple-unit.js80
-rw-r--r--tests/rustdoc-js/tuple-unit.rs18
-rw-r--r--tests/rustdoc-js/type-parameters.js19
31 files changed, 812 insertions, 34 deletions
diff --git a/tests/rustdoc-js/assoc-type-backtrack.js b/tests/rustdoc-js/assoc-type-backtrack.js
new file mode 100644
index 00000000000..493e1a9910d
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-backtrack.js
@@ -0,0 +1,163 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'mytrait, mytrait2 -> T',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+        ],
+    },
+    {
+        'query': 'mytrait<U>, mytrait2 -> T',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+        ],
+    },
+    {
+        'query': 'mytrait<Item=U>, mytrait2 -> T',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+        ],
+    },
+    {
+        'query': 'mytrait<T>, mytrait2 -> T',
+        'correction': null,
+        'others': [],
+    },
+    {
+        'query': 'mytrait<Item=T>, mytrait2 -> T',
+        'correction': null,
+        'others': [],
+    },
+    {
+        'query': 'mytrait<T> -> Option<T>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
+        ],
+    },
+    {
+        'query': 'mytrait<Item=T> -> Option<T>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'next' },
+        ],
+    },
+    {
+        'query': 'mytrait<U> -> Option<T>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
+        ],
+    },
+    {
+        'query': 'mytrait<Item=U> -> Option<T>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
+        ],
+    },
+    // The first two define the base case.
+    {
+        'query': 'myintofuture<fut=myfuture<t>> -> myfuture<t>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    {
+        'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    // Unboxings of the one-argument case.
+    {
+        'query': 'myfuture<t> -> myfuture<t>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    {
+        'query': 'myintofuture<myfuture<t>> -> myfuture<t>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    // Invalid unboxing of the one-argument case.
+    // If you unbox one of the myfutures, you need to unbox both of them.
+    {
+        'query': 'myintofuture<fut=t> -> myfuture<t>',
+        'correction': null,
+        'others': [],
+    },
+    // Unboxings of the two-argument case.
+    {
+        'query': 'myintofuture<fut=t>, myintofuture<fut=t> -> t',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    {
+        'query': 'myintofuture<fut=myfuture>, myintofuture<fut=myfuture> -> myfuture',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    {
+        'query': 'myintofuture<myfuture>, myintofuture<myfuture> -> myfuture',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    {
+        'query': 'myfuture<t>, myfuture<t> -> myfuture<t>',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
+    },
+    // Invalid unboxings of the two-argument case.
+    // If you unbox one of the myfutures, you need to unbox all of them.
+    {
+        'query': 'myintofuture<fut=t>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
+        'correction': null,
+        'others': [],
+    },
+    {
+        'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=t> -> myfuture<t>',
+        'correction': null,
+        'others': [],
+    },
+    {
+        'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=myfuture<t>> -> t',
+        'correction': null,
+        'others': [],
+    },
+    // different generics don't match up either
+    {
+        'query': 'myintofuture<fut=myfuture<u>>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
+        'correction': null,
+        'others': [],
+    },
+    {
+        'query': 'myintofuture<output=t> -> myfuture<tt>',
+        'correction': null,
+        'others': [],
+    },
+];
diff --git a/tests/rustdoc-js/assoc-type-backtrack.rs b/tests/rustdoc-js/assoc-type-backtrack.rs
new file mode 100644
index 00000000000..c3cdd78c6e1
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-backtrack.rs
@@ -0,0 +1,38 @@
+pub trait MyTrait2<X> {
+    type Output;
+}
+
+pub trait MyTrait {
+    type Item;
+    fn next(&mut self) -> Option<Self::Item>;
+    fn fold<B, F>(self, init: B, f: F) -> B where
+        Self: Sized,
+        F: MyTrait2<(B, Self::Item), Output=B>;
+}
+
+pub struct Cloned<I>(I);
+
+impl<'a, T, I> MyTrait for Cloned<I> where
+    T: 'a + Clone,
+    I: MyTrait<Item = &'a T>
+{
+    type Item = T;
+    fn next(&mut self) -> Option<Self::Item> { loop {} }
+    fn fold<B, F>(self, init: B, f: F) -> B where
+        Self: Sized,
+        F: MyTrait2<(B, Self::Item), Output=B>
+    {
+        loop {}
+    }
+}
+
+pub trait MyFuture {
+    type Output;
+}
+
+pub trait MyIntoFuture {
+    type Output;
+    type Fut: MyFuture<Output=Self::Output>;
+    fn into_future(self) -> Self::Fut;
+    fn into_future_2(self, other: Self) -> Self::Fut;
+}
diff --git a/tests/rustdoc-js/assoc-type-loop.js b/tests/rustdoc-js/assoc-type-loop.js
new file mode 100644
index 00000000000..f0192371ab4
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-loop.js
@@ -0,0 +1,9 @@
+// Crash reduction of
+// https://github.com/rust-lang/rust/issues/118242
+
+const EXPECTED = [
+    {
+        'query': 't',
+        'correction': null,
+    },
+];
diff --git a/tests/rustdoc-js/assoc-type-loop.rs b/tests/rustdoc-js/assoc-type-loop.rs
new file mode 100644
index 00000000000..f123c83f50f
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-loop.rs
@@ -0,0 +1,35 @@
+#![crate_name="foo"]
+
+// reduced from sqlx 0.7.3
+use std::future::Future;
+use std::pin::Pin;
+use std::ops::{Deref, DerefMut};
+pub enum Error {}
+pub trait Acquire<'c> {
+    type Database: Database;
+    type Connection: Deref<Target = <Self::Database as Database>::Connection> + DerefMut + Send;
+}
+pub trait Database {
+    type Connection: Connection<Database = Self>;
+}
+pub trait Connection {
+    type Database: Database;
+    type Options: ConnectionOptions<Connection = Self>;
+    fn begin(
+        &mut self
+    ) -> Pin<Box<dyn Future<Output = Result<Transaction<'_, Self::Database>, Error>> + Send + '_>>
+    where
+        Self: Sized;
+}
+pub trait ConnectionOptions {
+    type Connection: Connection;
+}
+pub struct Transaction<'c, DB: Database> {
+    _db: &'c DB,
+}
+impl<'t, 'c, DB: Database> Acquire<'t> for &'t mut Transaction<'c, DB>
+    where <DB as Database>::Connection: Send
+{
+    type Database = DB;
+    type Connection = &'t mut <DB as Database>::Connection;
+}
diff --git a/tests/rustdoc-js/assoc-type.js b/tests/rustdoc-js/assoc-type.js
new file mode 100644
index 00000000000..eec4e7a8258
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type.js
@@ -0,0 +1,56 @@
+// exact-check
+
+const EXPECTED = [
+    // if I just use generics, then the generics version
+    // and the type binding version both show up
+    {
+        'query': 'iterator<something> -> u32',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
+        ],
+    },
+    {
+        'query': 'iterator<something>',
+        'correction': null,
+        'in_args': [
+            { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
+        ],
+    },
+    {
+        'query': 'something',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type', 'name': 'Something' },
+        ],
+        'in_args': [
+            { 'path': 'assoc_type::my', 'name': 'other_fn' },
+            { 'path': 'assoc_type', 'name': 'my_fn' },
+        ],
+    },
+    // if I write an explicit binding, only it shows up
+    {
+        'query': 'iterator<item=something> -> u32',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type', 'name': 'my_fn' },
+        ],
+    },
+    // case insensitivity
+    {
+        'query': 'iterator<ItEm=sOmEtHiNg> -> u32',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type', 'name': 'my_fn' },
+        ],
+    },
+    // wrong binding name, no result
+    {
+        'query': 'iterator<something=something> -> u32',
+        'correction': null,
+        'in_args': [],
+        'others': [],
+    },
+];
diff --git a/tests/rustdoc-js/assoc-type.rs b/tests/rustdoc-js/assoc-type.rs
new file mode 100644
index 00000000000..e12e73cb546
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type.rs
@@ -0,0 +1,12 @@
+pub fn my_fn<X: Iterator<Item = Something>>(_x: X) -> u32 {
+    3
+}
+
+pub struct Something;
+
+pub mod my {
+    pub trait Iterator<T> {}
+    pub fn other_fn<X: Iterator<crate::Something>>(_: X) -> u32 {
+        3
+    }
+}
diff --git a/tests/rustdoc-js/big-result.js b/tests/rustdoc-js/big-result.js
new file mode 100644
index 00000000000..07961d196f4
--- /dev/null
+++ b/tests/rustdoc-js/big-result.js
@@ -0,0 +1,39 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'First',
+        'in_args': (function() {
+            // Generate the list of 200 items that should match.
+            const results = [];
+            function generate(lx, ly) {
+                for (const x of lx) {
+                    for (const y of ly) {
+                        results.push({
+                            'path': `big_result::${y}`,
+                            'name': x,
+                        });
+                    }
+                }
+            }
+            // Fewest parameters that still match go on top.
+            generate(
+                ['u', 'v', 'w', 'x', 'y'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['p', 'q', 'r', 's', 't'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['k', 'l', 'm', 'n', 'o'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            generate(
+                ['f', 'g', 'h', 'i', 'j'],
+                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
+            );
+            return results;
+        })(),
+    },
+];
diff --git a/tests/rustdoc-js/big-result.rs b/tests/rustdoc-js/big-result.rs
new file mode 100644
index 00000000000..4dfecd6aaad
--- /dev/null
+++ b/tests/rustdoc-js/big-result.rs
@@ -0,0 +1,61 @@
+#![feature(concat_idents)]
+#![allow(nonstandard_style)]
+/// Generate 250 items that all match the query, starting with the longest.
+/// Those long items should be dropped from the result set, and the short ones
+/// should be shown instead.
+macro_rules! generate {
+    ([$($x:ident),+], $y:tt, $z:tt) => {
+        $(
+            generate!(@ $x, $y, $z);
+        )+
+    };
+    (@ $x:ident , [$($y:ident),+], $z:tt) => {
+        pub struct $x;
+        $(
+            generate!(@@ $x, $y, $z);
+        )+
+    };
+    (@@ $x:ident , $y:ident, [$($z:ident: $zt:ident),+]) => {
+        impl $y {
+            pub fn $x($($z: $zt,)+) {}
+        }
+    }
+}
+
+pub struct First;
+pub struct Second;
+pub struct Third;
+pub struct Fourth;
+pub struct Fifth;
+
+generate!(
+    [a, b, c, d, e],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third, d: Fourth, e: Fifth]
+);
+
+generate!(
+    [f, g, h, i, j],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third, d: Fourth]
+);
+
+generate!(
+    [k, l, m, n, o],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second, c: Third]
+);
+
+generate!(
+    // reverse it, just to make sure they're alphabetized
+    // in the result set when all else is equal
+    [t, s, r, q, p],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First, b: Second]
+);
+
+generate!(
+    [u, v, w, x, y],
+    [a, b, c, d, e, f, g, h, i, j],
+    [a: First]
+);
diff --git a/tests/rustdoc-js/enum-variant-not-type.js b/tests/rustdoc-js/enum-variant-not-type.js
new file mode 100644
index 00000000000..b0f1ec66658
--- /dev/null
+++ b/tests/rustdoc-js/enum-variant-not-type.js
@@ -0,0 +1,70 @@
+const EXPECTED = [
+    {
+        'query': 'T -> T',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type',
+                'name': 'my_fn',
+            },
+            {
+                'path': 'enum_variant_not_type::AutoCorrectConfounder',
+                'name': 'assoc_type_acts_like_generic',
+            },
+        ],
+    },
+    {
+        'query': 'InsertUnnecessarilyLongTypeNameHere -> InsertUnnecessarilyLongTypeNameHere',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type',
+                'name': 'my_fn',
+            },
+            {
+                'path': 'enum_variant_not_type::AutoCorrectConfounder',
+                'name': 'assoc_type_acts_like_generic',
+            },
+        ],
+    },
+    {
+        'query': 'InsertUnnecessarilyLongTypeNameHere',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type::AutoCorrectConfounder',
+                'name': 'InsertUnnecessarilyLongTypeNameHere',
+            },
+        ],
+    },
+    {
+        'query': 'InsertUnnecessarilyLongTypeNameHereX',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type::AutoCorrectConfounder',
+                'name': 'InsertUnnecessarilyLongTypeNameHere',
+            },
+        ],
+    },
+    {
+        'query': 'T',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type::MyTrait',
+                'name': 'T',
+            },
+        ],
+    },
+    {
+        'query': 'T',
+        'correction': null,
+        'others': [
+            {
+                'path': 'enum_variant_not_type::MyTrait',
+                'name': 'T',
+            },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/enum-variant-not-type.rs b/tests/rustdoc-js/enum-variant-not-type.rs
new file mode 100644
index 00000000000..421bddf6289
--- /dev/null
+++ b/tests/rustdoc-js/enum-variant-not-type.rs
@@ -0,0 +1,14 @@
+pub trait MyTrait {
+    // Reduced from `arti` crate.
+    // https://tpo.pages.torproject.net/core/doc/rust/tor_config/list_builder/trait.DirectDefaultEmptyListBuilderAccessors.html#associatedtype.T
+    type T;
+    fn not_appearing(&self) -> Option<&Self::T>;
+}
+
+pub fn my_fn<X>(t: X) -> X { t }
+
+pub trait AutoCorrectConfounder {
+    type InsertUnnecessarilyLongTypeNameHere;
+    fn assoc_type_acts_like_generic(&self, x: &Self::InsertUnnecessarilyLongTypeNameHere)
+        -> Option<&Self::InsertUnnecessarilyLongTypeNameHere>;
+}
diff --git a/tests/rustdoc-js/exact-match.js b/tests/rustdoc-js/exact-match.js
index ce3a76f9b7d..9e47d27490b 100644
--- a/tests/rustdoc-js/exact-match.js
+++ b/tests/rustdoc-js/exact-match.js
@@ -3,6 +3,5 @@ const EXPECTED = {
     'others': [
         { 'path': 'exact_match::Si', 'name': 'pc' },
         { 'path': 'exact_match::Psi', 'name': 'pc' },
-        { 'path': 'exact_match::Si', 'name': 'pa' },
     ],
 };
diff --git a/tests/rustdoc-js/full-path-function.js b/tests/rustdoc-js/full-path-function.js
index 48be51b156f..0464f792217 100644
--- a/tests/rustdoc-js/full-path-function.js
+++ b/tests/rustdoc-js/full-path-function.js
@@ -4,16 +4,16 @@ const EXPECTED = [
     {
         'query': 'sac -> usize',
         'others': [
-            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
             { 'path': 'full_path_function::b::Sac', 'name': 'len' },
             { 'path': 'full_path_function::sac::Sac', 'name': 'len' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
         ],
     },
     {
         'query': 'b::sac -> usize',
         'others': [
-            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
             { 'path': 'full_path_function::b::Sac', 'name': 'len' },
+            { 'path': 'full_path_function::b::Sac', 'name': 'bar' },
         ],
     },
     {
diff --git a/tests/rustdoc-js/gat.js b/tests/rustdoc-js/gat.js
new file mode 100644
index 00000000000..7cb6a85d135
--- /dev/null
+++ b/tests/rustdoc-js/gat.js
@@ -0,0 +1,57 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'foo<assoc<u8>=u8> -> u32',
+        'correction': null,
+        'in_args': [],
+        'others': [
+            { 'path': 'gat', 'name': 'sample' },
+        ],
+    },
+    {
+        'query': 'foo<assoc<u8>=u8> -> !',
+        'correction': null,
+        'in_args': [],
+        'others': [
+            { 'path': 'gat', 'name': 'synergy' },
+        ],
+    },
+    {
+        'query': 'foo<assoc<u8>=u8>',
+        'correction': null,
+        'in_args': [
+            { 'path': 'gat', 'name': 'sample' },
+            { 'path': 'gat', 'name': 'synergy' },
+        ],
+    },
+    {
+        'query': 'foo<assoc<u8>=u32>',
+        'correction': null,
+        'in_args': [
+            { 'path': 'gat', 'name': 'consider' },
+        ],
+    },
+    {
+        // This one is arguably a bug, because the way rustdoc
+        // stores GATs in the search index is sloppy, but it's
+        // precise enough to match most of the samples in the
+        // GAT initiative repo
+        'query': 'foo<assoc<u32>=u8>',
+        'correction': null,
+        'in_args': [
+            { 'path': 'gat', 'name': 'consider' },
+        ],
+    },
+    {
+        // This one is arguably a bug, because the way rustdoc
+        // stores GATs in the search index is sloppy, but it's
+        // precise enough to match most of the samples in the
+        // GAT initiative repo
+        'query': 'foo<assoc<T>=T>',
+        'correction': null,
+        'in_args': [
+            { 'path': 'gat', 'name': 'integrate' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/gat.rs b/tests/rustdoc-js/gat.rs
new file mode 100644
index 00000000000..b4861cc683f
--- /dev/null
+++ b/tests/rustdoc-js/gat.rs
@@ -0,0 +1,8 @@
+pub trait Foo {
+    type Assoc<T>;
+}
+
+pub fn sample<X: Foo<Assoc<u8> = u8>>(_: X) -> u32 { loop {} }
+pub fn synergy(_: impl Foo<Assoc<u8> = u8>) -> ! { loop {} }
+pub fn consider(_: impl Foo<Assoc<u8> = u32>) -> bool { loop {} }
+pub fn integrate<T>(_: impl Foo<Assoc<T> = T>) -> T { loop {} }
diff --git a/tests/rustdoc-js/generics.js b/tests/rustdoc-js/generics.js
index ebc92ccfc05..b3ca0af3056 100644
--- a/tests/rustdoc-js/generics.js
+++ b/tests/rustdoc-js/generics.js
@@ -1,4 +1,5 @@
 // exact-check
+// ignore-order
 
 const EXPECTED = [
     {
diff --git a/tests/rustdoc-js/generics2.js b/tests/rustdoc-js/generics2.js
new file mode 100644
index 00000000000..f08704349a4
--- /dev/null
+++ b/tests/rustdoc-js/generics2.js
@@ -0,0 +1,22 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'outside<U>, outside<V> -> outside<W>',
+        'others': [],
+    },
+    {
+        'query': 'outside<V>, outside<U> -> outside<W>',
+        'others': [],
+    },
+    {
+        'query': 'outside<U>, outside<U> -> outside<W>',
+        'others': [],
+    },
+    {
+        'query': 'outside<U>, outside<U> -> outside<U>',
+        'others': [
+            {"path": "generics2", "name": "should_match_3"}
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/generics2.rs b/tests/rustdoc-js/generics2.rs
new file mode 100644
index 00000000000..1177ade6831
--- /dev/null
+++ b/tests/rustdoc-js/generics2.rs
@@ -0,0 +1,13 @@
+pub struct Outside<T>(T);
+
+pub fn no_match<U, V>(a: Outside<U>, b: Outside<V>) -> (Outside<U>, Outside<V>) {
+    unimplemented!();
+}
+
+pub fn no_match_2<U, V>(a: Outside<V>, b: Outside<U>) -> (Outside<U>, Outside<V>) {
+    unimplemented!();
+}
+
+pub fn should_match_3<U>(a: Outside<U>, b: Outside<U>) -> (Outside<U>, Outside<U>) {
+    unimplemented!();
+}
diff --git a/tests/rustdoc-js/impl-trait.js b/tests/rustdoc-js/impl-trait.js
index 00d67d639bd..8bb3f2d3e99 100644
--- a/tests/rustdoc-js/impl-trait.js
+++ b/tests/rustdoc-js/impl-trait.js
@@ -39,8 +39,8 @@ const EXPECTED = [
             { 'path': 'impl_trait', 'name': 'Aaaaaaa' },
         ],
         'in_args': [
-            { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+            { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
         ],
         'returned': [
             { 'path': 'impl_trait', 'name': 'bbbbbbb' },
diff --git a/tests/rustdoc-js/module-substring.js b/tests/rustdoc-js/module-substring.js
index 7a10397ebc6..74c421d7f0b 100644
--- a/tests/rustdoc-js/module-substring.js
+++ b/tests/rustdoc-js/module-substring.js
@@ -1,7 +1,15 @@
-const EXPECTED = {
-    'query': 'ig::pc',
-    'others': [
-        { 'path': 'module_substring::Sig', 'name': 'pc' },
-        { 'path': 'module_substring::Si', 'name': 'pc' },
-    ],
-};
+const EXPECTED = [
+    {
+        'query': 'ig::pc',
+        'others': [
+            { 'path': 'module_substring::Sig', 'name': 'pc' },
+        ],
+    },
+    {
+        'query': 'si::pc',
+        'others': [
+            { 'path': 'module_substring::Si', 'name': 'pc' },
+            { 'path': 'module_substring::Sig', 'name': 'pc' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/never-search.js b/tests/rustdoc-js/never-search.js
index ed24d693133..9f18370c2f5 100644
--- a/tests/rustdoc-js/never-search.js
+++ b/tests/rustdoc-js/never-search.js
@@ -43,4 +43,14 @@ const EXPECTED = [
             { 'path': 'never_search', 'name': 'box_uninteresting' },
         ],
     },
+    {
+        'query': 'box<item=!>',
+        'in_args': [],
+        'returned': [],
+    },
+    {
+        'query': 'box<item=never>',
+        'in_args': [],
+        'returned': [],
+    },
 ];
diff --git a/tests/rustdoc-js/path-maxeditdistance.js b/tests/rustdoc-js/path-maxeditdistance.js
new file mode 100644
index 00000000000..73b24a6dddf
--- /dev/null
+++ b/tests/rustdoc-js/path-maxeditdistance.js
@@ -0,0 +1,35 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'xxxxxxxxxxx::hocuspocusprestidigitation',
+        // do not match abracadabra::hocuspocusprestidigitation
+        'others': [],
+    },
+    {
+        // exact match
+        'query': 'abracadabra::hocuspocusprestidigitation',
+        'others': [
+            { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
+        ],
+    },
+    {
+        // swap br/rb; that's edit distance 2, where maxPathEditDistance = 3 (11 / 3)
+        'query': 'arbacadarba::hocuspocusprestidigitation',
+        'others': [
+            { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
+        ],
+    },
+    {
+        // truncate 5 chars, where maxEditDistance = 7 (21 / 3)
+        'query': 'abracadarba::hocusprestidigitation',
+        'others': [
+            { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
+        ],
+    },
+    {
+        // truncate 9 chars, where maxEditDistance = 5 (17 / 3)
+        'query': 'abracadarba::hprestidigitation',
+        'others': [],
+    },
+];
diff --git a/tests/rustdoc-js/path-maxeditdistance.rs b/tests/rustdoc-js/path-maxeditdistance.rs
new file mode 100644
index 00000000000..3861280d59b
--- /dev/null
+++ b/tests/rustdoc-js/path-maxeditdistance.rs
@@ -0,0 +1,3 @@
+#![crate_name="abracadabra"]
+
+pub struct HocusPocusPrestidigitation;
diff --git a/tests/rustdoc-js/path-ordering.js b/tests/rustdoc-js/path-ordering.js
index f2e6fe2fa61..73d3f4b2755 100644
--- a/tests/rustdoc-js/path-ordering.js
+++ b/tests/rustdoc-js/path-ordering.js
@@ -1,13 +1,13 @@
 // exact-check
 
 const EXPECTED = {
-    'query': 'b::ccccccc',
+    'query': 'bbbbbb::ccccccc',
     'others': [
         // `ccccccc` is an exact match for all three of these.
         // However `b` is a closer match for `bb` than for any
         // of the others, so it ought to go first.
-        { 'path': 'path_ordering::bb', 'name': 'Ccccccc' },
-        { 'path': 'path_ordering::aa', 'name': 'Ccccccc' },
-        { 'path': 'path_ordering::dd', 'name': 'Ccccccc' },
+        { 'path': 'path_ordering::bbbbbb', 'name': 'Ccccccc' },
+        { 'path': 'path_ordering::abbbbb', 'name': 'Ccccccc' },
+        { 'path': 'path_ordering::dbbbbb', 'name': 'Ccccccc' },
     ],
 };
diff --git a/tests/rustdoc-js/path-ordering.rs b/tests/rustdoc-js/path-ordering.rs
index 7843cf7f9dc..71e24923ed1 100644
--- a/tests/rustdoc-js/path-ordering.rs
+++ b/tests/rustdoc-js/path-ordering.rs
@@ -1,9 +1,9 @@
-pub mod dd {
+pub mod dbbbbb {
     pub struct Ccccccc;
 }
-pub mod aa {
+pub mod abbbbb {
     pub struct Ccccccc;
 }
-pub mod bb {
+pub mod bbbbbb {
     pub struct Ccccccc;
 }
diff --git a/tests/rustdoc-js/substring.js b/tests/rustdoc-js/substring.js
index 96efa992bb6..b791ac4bfd1 100644
--- a/tests/rustdoc-js/substring.js
+++ b/tests/rustdoc-js/substring.js
@@ -1,7 +1,15 @@
-const EXPECTED = {
-    'query': 'waker_from',
-    'others': [
-        { 'path': 'substring::SuperWaker', 'name': 'local_waker_from_nonlocal' },
-        { 'path': 'substring::SuperWakerTask', 'name': 'local_waker_from_nonlocal' },
-    ],
-};
+const EXPECTED = [
+    {
+        'query': 'waker_from',
+        'others': [
+            { 'path': 'substring::SuperWaker', 'name': 'local_waker_from_nonlocal' },
+            { 'path': 'substring::SuperWakerTask', 'name': 'local_waker_from_nonlocal' },
+        ],
+    },
+    {
+        'query': 'my',
+        'others': [
+            { 'path': 'substring', 'name': 'm_y_substringmatching' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/substring.rs b/tests/rustdoc-js/substring.rs
index e729c722c79..ea88894d03d 100644
--- a/tests/rustdoc-js/substring.rs
+++ b/tests/rustdoc-js/substring.rs
@@ -19,3 +19,5 @@ impl SuperWakerTask {
     pub fn waker_non_local() {}
     pub fn from_non_local() {}
 }
+
+pub fn m_y_substringmatching() {}
diff --git a/tests/rustdoc-js/trait-methods.js b/tests/rustdoc-js/trait-methods.js
new file mode 100644
index 00000000000..dafad5e4378
--- /dev/null
+++ b/tests/rustdoc-js/trait-methods.js
@@ -0,0 +1,12 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': 'mytrait<t> -> option<t>',
+        'correction': null,
+        'in_args': [],
+        'others': [
+            { 'path': 'trait_methods::MyTrait', 'name': 'next' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/trait-methods.rs b/tests/rustdoc-js/trait-methods.rs
new file mode 100644
index 00000000000..c88f5edfd55
--- /dev/null
+++ b/tests/rustdoc-js/trait-methods.rs
@@ -0,0 +1,4 @@
+pub trait MyTrait {
+    type Item;
+    fn next(&mut self) -> Option<Self::Item>;
+}
diff --git a/tests/rustdoc-js/tuple-unit.js b/tests/rustdoc-js/tuple-unit.js
new file mode 100644
index 00000000000..d24a3da328c
--- /dev/null
+++ b/tests/rustdoc-js/tuple-unit.js
@@ -0,0 +1,80 @@
+// exact-check
+
+const EXPECTED = [
+    {
+        'query': '()',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'side_effect' },
+            { 'path': 'tuple_unit', 'name': 'one' },
+            { 'path': 'tuple_unit', 'name': 'two' },
+            { 'path': 'tuple_unit', 'name': 'nest' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': 'primitive:unit',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'side_effect' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': 'primitive:tuple',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'one' },
+            { 'path': 'tuple_unit', 'name': 'two' },
+            { 'path': 'tuple_unit', 'name': 'nest' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(P)',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'not_tuple' },
+            { 'path': 'tuple_unit', 'name': 'one' },
+            { 'path': 'tuple_unit', 'name': 'two' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(P,)',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'one' },
+            { 'path': 'tuple_unit', 'name': 'two' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(P, P)',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'two' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(P, ())',
+        'returned': [],
+        'in_args': [],
+    },
+    {
+        'query': '(Q, ())',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'nest' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(R)',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'nest' },
+        ],
+        'in_args': [],
+    },
+    {
+        'query': '(u32)',
+        'returned': [
+            { 'path': 'tuple_unit', 'name': 'nest' },
+        ],
+        'in_args': [],
+    },
+];
diff --git a/tests/rustdoc-js/tuple-unit.rs b/tests/rustdoc-js/tuple-unit.rs
new file mode 100644
index 00000000000..93f9a671cbc
--- /dev/null
+++ b/tests/rustdoc-js/tuple-unit.rs
@@ -0,0 +1,18 @@
+pub struct P;
+pub struct Q;
+pub struct R<T>(T);
+
+// Checks that tuple and unit both work
+pub fn side_effect() { }
+
+// Check a non-tuple
+pub fn not_tuple() -> P { loop {} }
+
+// Check a 1-tuple
+pub fn one() -> (P,) { loop {} }
+
+// Check a 2-tuple
+pub fn two() -> (P,P) { loop {} }
+
+// Check a nested tuple
+pub fn nest() -> (Q, R<(u32,)>) { loop {} }
diff --git a/tests/rustdoc-js/type-parameters.js b/tests/rustdoc-js/type-parameters.js
index e695f189bb6..e045409e507 100644
--- a/tests/rustdoc-js/type-parameters.js
+++ b/tests/rustdoc-js/type-parameters.js
@@ -1,20 +1,19 @@
 // exact-check
-// ignore-order
 
 const EXPECTED = [
     {
         query: '-> trait:Some',
         others: [
-            { path: 'foo', name: 'alef' },
             { path: 'foo', name: 'alpha' },
+            { path: 'foo', name: 'alef' },
         ],
     },
     {
         query: '-> generic:T',
         others: [
+            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alef' },
-            { path: 'foo', name: 'beta' },
         ],
     },
     {
@@ -44,38 +43,40 @@ const EXPECTED = [
     {
         query: 'Other, Other',
         others: [
-            { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'generic:T',
         in_args: [
-            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'beta' },
-            { path: 'foo', name: 'other' },
+            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'generic:Other',
         in_args: [
-            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'beta' },
-            { path: 'foo', name: 'other' },
+            { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'trait:Other',
         in_args: [
-            { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
+            { path: 'foo', name: 'other' },
         ],
     },
     {
         query: 'Other',
         in_args: [
+            // because function is called "other", it's sorted first
+            // even though it has higher type distance
             { path: 'foo', name: 'other' },
             { path: 'foo', name: 'alternate' },
         ],