about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/utils.rs61
-rw-r--r--src/librustdoc/html/render/print_item.rs19
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/Makefile2
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt4
-rw-r--r--src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs3
-rw-r--r--src/test/run-make-fulldeps/coverage/unused_mod.rs6
-rw-r--r--src/test/rustdoc/decl_macro.rs12
-rw-r--r--src/test/rustdoc/issue-88600.rs5
-rw-r--r--src/test/rustdoc/macro-generated-macro.rs14
-rw-r--r--src/test/rustdoc/macros.rs8
-rw-r--r--src/test/rustdoc/reexports-priv.rs8
-rw-r--r--src/test/rustdoc/reexports.rs4
-rw-r--r--src/test/rustdoc/tuple-struct-fields-doc.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr56
m---------src/tools/cargo0
-rw-r--r--src/tools/tidy/src/deps.rs1
17 files changed, 134 insertions, 87 deletions
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index f0e9b716081..b14430d10e9 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -17,6 +17,8 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
+use rustc_session::parse::ParseSess;
+use rustc_span::source_map::FilePathMapping;
 use rustc_span::symbol::{kw, sym, Symbol};
 use std::fmt::Write as _;
 use std::mem;
@@ -486,20 +488,67 @@ crate const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
 /// Render a sequence of macro arms in a format suitable for displaying to the user
 /// as part of an item declaration.
 pub(super) fn render_macro_arms<'a>(
+    tcx: TyCtxt<'_>,
     matchers: impl Iterator<Item = &'a TokenTree>,
     arm_delim: &str,
 ) -> String {
     let mut out = String::new();
     for matcher in matchers {
-        writeln!(out, "    {} => {{ ... }}{}", render_macro_matcher(matcher), arm_delim).unwrap();
+        writeln!(out, "    {} => {{ ... }}{}", render_macro_matcher(tcx, matcher), arm_delim)
+            .unwrap();
     }
     out
 }
 
 /// Render a macro matcher in a format suitable for displaying to the user
 /// as part of an item declaration.
-pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
-    rustc_ast_pretty::pprust::tt_to_string(matcher)
+pub(super) fn render_macro_matcher(tcx: TyCtxt<'_>, matcher: &TokenTree) -> String {
+    if let Some(snippet) = snippet_equal_to_token(tcx, matcher) {
+        snippet
+    } else {
+        rustc_ast_pretty::pprust::tt_to_string(matcher)
+    }
+}
+
+/// Find the source snippet for this token's Span, reparse it, and return the
+/// snippet if the reparsed TokenTree matches the argument TokenTree.
+fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String> {
+    // Find what rustc thinks is the source snippet.
+    // This may not actually be anything meaningful if this matcher was itself
+    // generated by a macro.
+    let source_map = tcx.sess.source_map();
+    let span = matcher.span();
+    let snippet = source_map.span_to_snippet(span).ok()?;
+
+    // Create a Parser.
+    let sess = ParseSess::new(FilePathMapping::empty());
+    let file_name = source_map.span_to_filename(span);
+    let mut parser =
+        match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) {
+            Ok(parser) => parser,
+            Err(diagnostics) => {
+                for mut diagnostic in diagnostics {
+                    diagnostic.cancel();
+                }
+                return None;
+            }
+        };
+
+    // Reparse a single token tree.
+    let mut reparsed_trees = match parser.parse_all_token_trees() {
+        Ok(reparsed_trees) => reparsed_trees,
+        Err(mut diagnostic) => {
+            diagnostic.cancel();
+            return None;
+        }
+    };
+    if reparsed_trees.len() != 1 {
+        return None;
+    }
+    let reparsed_tree = reparsed_trees.pop().unwrap();
+
+    // Compare against the original tree.
+    if reparsed_tree.eq_unspanned(matcher) { Some(snippet) } else { None }
 }
 
 pub(super) fn display_macro_source(
@@ -514,21 +563,21 @@ pub(super) fn display_macro_source(
     let matchers = tts.chunks(4).map(|arm| &arm[0]);
 
     if def.macro_rules {
-        format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
+        format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(cx.tcx, matchers, ";"))
     } else {
         if matchers.len() <= 1 {
             format!(
                 "{}macro {}{} {{\n    ...\n}}",
                 vis.to_src_with_space(cx.tcx, def_id),
                 name,
-                matchers.map(render_macro_matcher).collect::<String>(),
+                matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::<String>(),
             )
         } else {
             format!(
                 "{}macro {} {{\n{}}}",
                 vis.to_src_with_space(cx.tcx, def_id),
                 name,
-                render_macro_arms(matchers, ","),
+                render_macro_arms(cx.tcx, matchers, ","),
             )
         }
     }
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 11426cb6571..5431bd8565b 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1126,18 +1126,27 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
             w.write_str("</h3>");
 
             use crate::clean::Variant;
-            if let Some((extra, fields)) = match *variant.kind {
-                clean::VariantItem(Variant::Struct(ref s)) => Some(("", &s.fields)),
-                clean::VariantItem(Variant::Tuple(ref fields)) => Some(("Tuple ", fields)),
+
+            let heading_and_fields = match &*variant.kind {
+                clean::VariantItem(Variant::Struct(s)) => Some(("Fields", &s.fields)),
+                // Documentation on tuple variant fields is rare, so to reduce noise we only emit
+                // the section if at least one field is documented.
+                clean::VariantItem(Variant::Tuple(fields))
+                    if fields.iter().any(|f| f.doc_value().is_some()) =>
+                {
+                    Some(("Tuple Fields", fields))
+                }
                 _ => None,
-            } {
+            };
+
+            if let Some((heading, fields)) = heading_and_fields {
                 let variant_id = cx.derive_id(format!(
                     "{}.{}.fields",
                     ItemType::Variant,
                     variant.name.as_ref().unwrap()
                 ));
                 write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
-                write!(w, "<h4>{extra}Fields</h4>", extra = extra,);
+                write!(w, "<h4>{heading}</h4>", heading = heading);
                 document_non_exhaustive(w, variant);
                 for field in fields {
                     match *field.kind {
diff --git a/src/test/run-make-fulldeps/coverage-reports/Makefile b/src/test/run-make-fulldeps/coverage-reports/Makefile
index 9122e0406c2..094d6b3ebf5 100644
--- a/src/test/run-make-fulldeps/coverage-reports/Makefile
+++ b/src/test/run-make-fulldeps/coverage-reports/Makefile
@@ -64,7 +64,7 @@ endif
 # if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
 # appear to be normalized to `/` in those files, thankfully.)
 LLVM_COV_IGNORE_FILES=\
-	--ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs)'
+	--ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs|unused_mod.rs)'
 
 all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs))
 
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt
new file mode 100644
index 00000000000..82d6fccc271
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.unused_mod.txt
@@ -0,0 +1,4 @@
+    1|      0|pub fn never_called_function() {
+    2|      0|    println!("I am never called");
+    3|      0|}
+
diff --git a/src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs b/src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs
new file mode 100644
index 00000000000..ae1cc1531ed
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/lib/unused_mod_helper.rs
@@ -0,0 +1,3 @@
+pub fn never_called_function() {
+    println!("I am never called");
+}
diff --git a/src/test/run-make-fulldeps/coverage/unused_mod.rs b/src/test/run-make-fulldeps/coverage/unused_mod.rs
new file mode 100644
index 00000000000..679b4e53188
--- /dev/null
+++ b/src/test/run-make-fulldeps/coverage/unused_mod.rs
@@ -0,0 +1,6 @@
+#[path = "lib/unused_mod_helper.rs"]
+mod unused_module;
+
+fn main() {
+    println!("hello world!");
+}
diff --git a/src/test/rustdoc/decl_macro.rs b/src/test/rustdoc/decl_macro.rs
index fe19dadbe02..94ade31b5e5 100644
--- a/src/test/rustdoc/decl_macro.rs
+++ b/src/test/rustdoc/decl_macro.rs
@@ -9,7 +9,7 @@ pub macro my_macro() {
 
 }
 
-// @has decl_macro/macro.my_macro_2.html //pre 'pub macro my_macro_2($($tok : tt) *) {'
+// @has decl_macro/macro.my_macro_2.html //pre 'pub macro my_macro_2($($tok:tt)*) {'
 // @has - //pre '...'
 // @has - //pre '}'
 pub macro my_macro_2($($tok:tt)*) {
@@ -18,8 +18,8 @@ pub macro my_macro_2($($tok:tt)*) {
 
 // @has decl_macro/macro.my_macro_multi.html //pre 'pub macro my_macro_multi {'
 // @has - //pre '(_) => { ... },'
-// @has - //pre '($foo : ident.$bar : expr) => { ... },'
-// @has - //pre '($($foo : literal), +) => { ... },'
+// @has - //pre '($foo:ident . $bar:expr) => { ... },'
+// @has - //pre '($($foo:literal),+) => { ... },'
 // @has - //pre '}'
 pub macro my_macro_multi {
     (_) => {
@@ -33,7 +33,7 @@ pub macro my_macro_multi {
     }
 }
 
-// @has decl_macro/macro.by_example_single.html //pre 'pub macro by_example_single($foo : expr) {'
+// @has decl_macro/macro.by_example_single.html //pre 'pub macro by_example_single($foo:expr) {'
 // @has - //pre '...'
 // @has - //pre '}'
 pub macro by_example_single {
@@ -42,12 +42,12 @@ pub macro by_example_single {
 
 mod a {
     mod b {
-        // @has decl_macro/a/b/macro.by_example_vis.html //pre 'pub(super) macro by_example_vis($foo : expr) {'
+        // @has decl_macro/a/b/macro.by_example_vis.html //pre 'pub(super) macro by_example_vis($foo:expr) {'
         pub(in super) macro by_example_vis {
             ($foo:expr) => {}
         }
         mod c {
-            // @has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($foo : expr) {'
+            // @has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($foo:expr) {'
             pub(in a) macro by_example_vis_named {
                 ($foo:expr) => {}
             }
diff --git a/src/test/rustdoc/issue-88600.rs b/src/test/rustdoc/issue-88600.rs
index 3761805b48b..fc63ed343bd 100644
--- a/src/test/rustdoc/issue-88600.rs
+++ b/src/test/rustdoc/issue-88600.rs
@@ -18,17 +18,18 @@ pub enum FooEnum {
     // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
     // @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
     // @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
-    MixedHiddenFirst(#[doc(hidden)] H, S),
+    MixedHiddenFirst(#[doc(hidden)] H, /** dox */ S),
     // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
     // @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
     // @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
-    MixedHiddenLast(S, #[doc(hidden)] H),
+    MixedHiddenLast(/** dox */ S, #[doc(hidden)] H),
     // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
     // @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
     // @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
     HiddenStruct {
         #[doc(hidden)]
         h: H,
+        /// dox
         s: S,
     },
 }
diff --git a/src/test/rustdoc/macro-generated-macro.rs b/src/test/rustdoc/macro-generated-macro.rs
new file mode 100644
index 00000000000..25d8bc3ec62
--- /dev/null
+++ b/src/test/rustdoc/macro-generated-macro.rs
@@ -0,0 +1,14 @@
+macro_rules! outer {
+    ($($matcher:tt)*) => {
+        #[macro_export]
+        macro_rules! inner {
+            (<= $($matcher)* =>) => {};
+        }
+    }
+}
+
+// @has macro_generated_macro/macro.inner.html //pre 'macro_rules! inner {'
+// @has - //pre '(<= type $($i : ident) :: * + $e : expr =>) => { ... };'
+outer!(type $($i:ident)::* + $e:expr);
+
+inner!(<= type foo::bar + x.sort() =>);
diff --git a/src/test/rustdoc/macros.rs b/src/test/rustdoc/macros.rs
index 1cd454720e7..ae0cf7a1478 100644
--- a/src/test/rustdoc/macros.rs
+++ b/src/test/rustdoc/macros.rs
@@ -1,7 +1,7 @@
 // @has macros/macro.my_macro.html //pre 'macro_rules! my_macro {'
 // @has - //pre '() => { ... };'
-// @has - //pre '($a : tt) => { ... };'
-// @has - //pre '($e : expr) => { ... };'
+// @has - //pre '($a:tt) => { ... };'
+// @has - //pre '($e:expr) => { ... };'
 #[macro_export]
 macro_rules! my_macro {
     () => [];
@@ -12,8 +12,8 @@ macro_rules! my_macro {
 // Check that exported macro defined in a module are shown at crate root.
 // @has macros/macro.my_sub_macro.html //pre 'macro_rules! my_sub_macro {'
 // @has - //pre '() => { ... };'
-// @has - //pre '($a : tt) => { ... };'
-// @has - //pre '($e : expr) => { ... };'
+// @has - //pre '($a:tt) => { ... };'
+// @has - //pre '($e:expr) => { ... };'
 mod sub {
     #[macro_export]
     macro_rules! my_sub_macro {
diff --git a/src/test/rustdoc/reexports-priv.rs b/src/test/rustdoc/reexports-priv.rs
index 95f74180749..aea9b9f2b39 100644
--- a/src/test/rustdoc/reexports-priv.rs
+++ b/src/test/rustdoc/reexports-priv.rs
@@ -5,7 +5,7 @@
 
 extern crate reexports;
 
-// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
 pub use reexports::addr_of;
 // @!has 'foo/macro.addr_of_crate.html'
 pub(crate) use reexports::addr_of_crate;
@@ -61,11 +61,11 @@ use reexports::UnionLocal;
 
 pub mod outer {
     pub mod inner {
-        // @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
+        // @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
         pub use reexports::addr_of;
-        // @has 'foo/outer/inner/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
+        // @has 'foo/outer/inner/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place:expr) {'
         pub(crate) use reexports::addr_of_crate;
-        // @has 'foo/outer/inner/macro.addr_of_super.html' '//*[@class="docblock item-decl"]' 'pub(in outer) macro addr_of_super($place : expr) {'
+        // @has 'foo/outer/inner/macro.addr_of_super.html' '//*[@class="docblock item-decl"]' 'pub(in outer) macro addr_of_super($place:expr) {'
         pub(super) use reexports::addr_of_super;
         // @!has 'foo/outer/inner/macro.addr_of_self.html'
         pub(self) use reexports::addr_of_self;
diff --git a/src/test/rustdoc/reexports.rs b/src/test/rustdoc/reexports.rs
index 3b315308470..7abcbfb6181 100644
--- a/src/test/rustdoc/reexports.rs
+++ b/src/test/rustdoc/reexports.rs
@@ -4,7 +4,7 @@
 
 extern crate reexports;
 
-// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
 pub use reexports::addr_of;
 // @!has 'foo/macro.addr_of_crate.html'
 pub(crate) use reexports::addr_of_crate;
@@ -60,7 +60,7 @@ use reexports::UnionLocal;
 
 pub mod outer {
     pub mod inner {
-        // @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
+        // @has 'foo/outer/inner/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place:expr) {'
         pub use reexports::addr_of;
         // @!has 'foo/outer/inner/macro.addr_of_crate.html'
         pub(crate) use reexports::addr_of_crate;
diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs
index 2e339fe8264..31426131bc2 100644
--- a/src/test/rustdoc/tuple-struct-fields-doc.rs
+++ b/src/test/rustdoc/tuple-struct-fields-doc.rs
@@ -24,6 +24,9 @@ pub struct Foo(
 // @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
 // @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
 // @matches - '//*[@id="variant.FooVariant.fields"]/h4' '^Fields$'
+// @has - '//*[@id="variant.BazVariant.fields"]//*[@class="docblock"]' 'dox'
+// @has - '//*[@id="variant.OtherVariant.fields"]//*[@class="docblock"]' 'dox'
+// @!matches - '//*[@id="variant.QuuxVariant.fields"]/h4' '^Tuple Fields$'
 pub enum Bar {
     BarVariant(
         /// Hello docs
@@ -33,4 +36,15 @@ pub enum Bar {
        /// hello
        x: u32,
     },
+    BazVariant(
+        String,
+        /// dox
+        u32,
+    ),
+    OtherVariant(
+        /// dox
+        String,
+        u32,
+    ),
+    QuuxVariant(String),
 }
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
index 579067340e8..cee8186dd8f 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -15,9 +15,5 @@ impl<W> Trait<W> for () {}
 
 fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
     //~^ ERROR non-defining opaque type use in defining scope
-    //~| ERROR non-defining opaque type use in defining scope
-    //~| ERROR non-defining opaque type use in defining scope
-    //~| ERROR `T` is part of concrete type but not used in parameter list
-    //~| ERROR `T` is part of concrete type but not used in parameter list
     ()
 }
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
index a77c0000f12..03e696fe898 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -1,34 +1,8 @@
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/bound_reduction2.rs:16:60
-   |
-LL |   fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   |  ____________________________________________________________^
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     ()
-LL | | }
-   | |_^
-
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/bound_reduction2.rs:16:60
-   |
-LL |   fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   |  ____________________________________________________________^
-LL | |
-LL | |
-LL | |
-...  |
-LL | |     ()
-LL | | }
-   | |_^
-
 error: non-defining opaque type use in defining scope
-  --> $DIR/bound_reduction2.rs:16:1
+  --> $DIR/bound_reduction2.rs:16:46
    |
 LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                              ^^^^^^^^^^^^^
    |
 note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
   --> $DIR/bound_reduction2.rs:9:10
@@ -36,35 +10,11 @@ note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
 LL | type Foo<V> = impl Trait<V>;
    |          ^
 
-error: non-defining opaque type use in defining scope
-  --> $DIR/bound_reduction2.rs:16:1
-   |
-LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: used non-generic type `_` for generic parameter
-  --> $DIR/bound_reduction2.rs:9:10
-   |
-LL | type Foo<V> = impl Trait<V>;
-   |          ^
-
-error: non-defining opaque type use in defining scope
-  --> $DIR/bound_reduction2.rs:16:1
-   |
-LL | fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: used non-generic type `_` for generic parameter
-  --> $DIR/bound_reduction2.rs:9:10
-   |
-LL | type Foo<V> = impl Trait<V>;
-   |          ^
-
 error: could not find defining uses
   --> $DIR/bound_reduction2.rs:9:15
    |
 LL | type Foo<V> = impl Trait<V>;
    |               ^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 358e79fe56fe374649275ca7aebaafd57ade0e8
+Subproject 06b9d31743210b788b130c8a484c2838afa6fc2
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 4c28655bc86..9d2aa0f21c8 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -73,6 +73,7 @@ const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_driver", "rustc_codegen_l
 const PERMITTED_DEPENDENCIES: &[&str] = &[
     "addr2line",
     "adler",
+    "ahash",
     "aho-corasick",
     "annotate-snippets",
     "ansi_term",