about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-29 19:29:49 +0000
committerbors <bors@rust-lang.org>2023-01-29 19:29:49 +0000
commite972bc8083d5228536dfd42913c8778b6bb04c8e (patch)
tree17b5e1e05361b5496f3ae02cca79afe6e2485a2b
parentc7bf469fecc75792e1598a0842ac40b361f0107b (diff)
parent97e6abad182c7506893634ba7495a86bbd62e078 (diff)
downloadrust-e972bc8083d5228536dfd42913c8778b6bb04c8e.tar.gz
rust-e972bc8083d5228536dfd42913c8778b6bb04c8e.zip
Auto merge of #107451 - matthiaskrgr:rollup-m4ucfu8, r=matthiaskrgr
Rollup of 11 pull requests

Successful merges:

 - #96763 (Fix maintainer validation message)
 - #106540 (Insert whitespace to avoid ident concatenation in suggestion)
 - #106763 (print why a test was ignored if its the only test specified)
 - #106769 (libtest: Print why a test was ignored if it's the only test specified.)
 - #106798 (Implement `signum` with `Ord`)
 - #107006 (Output tree representation on thir-tree)
 - #107078 (Update wording of invalid_doc_attributes docs.)
 - #107169 (Pass `--locked` to the x test tidy call)
 - #107431 (docs: remove colon from time header)
 - #107432 (rustdoc: remove unused class `has-srclink`)
 - #107448 (When stamp doesn't exist, should say Error, and print path to stamp file)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_driver/src/pretty.rs15
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs12
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/thir.rs1
-rw-r--r--compiler/rustc_middle/src/thir/print.rs881
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs10
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs2
-rw-r--r--compiler/rustc_session/src/config.rs11
-rw-r--r--library/core/src/num/int_macros.rs11
-rw-r--r--library/std/src/time.rs2
-rw-r--r--library/test/src/console.rs7
-rw-r--r--library/test/src/formatters/terse.rs9
-rw-r--r--library/test/src/tests.rs1
-rw-r--r--src/bootstrap/lib.rs3
-rwxr-xr-xsrc/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh6
-rwxr-xr-xsrc/etc/pre-push.sh2
-rw-r--r--src/librustdoc/html/render/mod.rs20
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/tools/compiletest/src/header.rs82
-rwxr-xr-xsrc/tools/publish_toolstate.py61
-rw-r--r--tests/rustdoc-gui/src-font-size.goml10
-rw-r--r--tests/rustdoc/anchors.no_const_anchor.html2
-rw-r--r--tests/rustdoc/anchors.no_const_anchor2.html2
-rw-r--r--tests/rustdoc/anchors.no_method_anchor.html2
-rw-r--r--tests/rustdoc/anchors.no_trait_method_anchor.html2
-rw-r--r--tests/rustdoc/anchors.no_tymethod_anchor.html2
-rw-r--r--tests/rustdoc/anchors.no_type_anchor.html2
-rw-r--r--tests/rustdoc/anchors.no_type_anchor2.html2
-rw-r--r--tests/rustdoc/async-fn.rs6
-rw-r--r--tests/rustdoc/const-fn.rs2
-rw-r--r--tests/rustdoc/const-generics/const-generic-slice.rs2
-rw-r--r--tests/rustdoc/doc-assoc-item.rs2
-rw-r--r--tests/rustdoc/duplicate_impls/issue-33054.rs4
-rw-r--r--tests/rustdoc/duplicated_impl.rs2
-rw-r--r--tests/rustdoc/empty-impl-block-private-with-doc.rs2
-rw-r--r--tests/rustdoc/empty-impl-block-private.rs2
-rw-r--r--tests/rustdoc/empty-impl-block.rs2
-rw-r--r--tests/rustdoc/impl-parts.rs2
-rw-r--r--tests/rustdoc/inline_cross/issue-31948-1.rs4
-rw-r--r--tests/rustdoc/inline_cross/issue-31948-2.rs6
-rw-r--r--tests/rustdoc/inline_cross/issue-31948.rs6
-rw-r--r--tests/rustdoc/issue-21474.rs2
-rw-r--r--tests/rustdoc/issue-33302.rs6
-rw-r--r--tests/rustdoc/issue-45584.rs8
-rw-r--r--tests/rustdoc/issue-50159.rs2
-rw-r--r--tests/rustdoc/issue-51236.rs2
-rw-r--r--tests/rustdoc/issue-53812.rs10
-rw-r--r--tests/rustdoc/issue-54705.rs4
-rw-r--r--tests/rustdoc/issue-55321.rs8
-rw-r--r--tests/rustdoc/issue-56822.rs2
-rw-r--r--tests/rustdoc/issue-60726.rs4
-rw-r--r--tests/rustdoc/issue-76501.rs2
-rw-r--r--tests/rustdoc/issue-78673.rs8
-rw-r--r--tests/rustdoc/mut-params.rs2
-rw-r--r--tests/rustdoc/negative-impl.rs4
-rw-r--r--tests/rustdoc/primitive-reference.rs2
-rw-r--r--tests/rustdoc/pub-method.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/basic.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/complex.rs2
-rw-r--r--tests/rustdoc/synthetic_auto/lifetimes.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/manual.rs8
-rw-r--r--tests/rustdoc/synthetic_auto/negative.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/nested.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/no-redundancy.rs2
-rw-r--r--tests/rustdoc/synthetic_auto/project.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/self-referential.rs2
-rw-r--r--tests/rustdoc/synthetic_auto/static-region.rs2
-rw-r--r--tests/rustdoc/typedef.rs4
-rw-r--r--tests/rustdoc/where.rs6
-rw-r--r--tests/ui/parser/trait-object-delimiters.rs2
-rw-r--r--tests/ui/parser/trait-object-delimiters.stderr28
-rw-r--r--tests/ui/thir-print/thir-flat.rs4
-rw-r--r--tests/ui/thir-print/thir-flat.stdout (renamed from tests/ui/thir-tree.stdout)12
-rw-r--r--tests/ui/thir-print/thir-tree-match.rs23
-rw-r--r--tests/ui/thir-print/thir-tree-match.stdout342
-rw-r--r--tests/ui/thir-print/thir-tree.rs (renamed from tests/ui/thir-tree.rs)0
-rw-r--r--tests/ui/thir-print/thir-tree.stdout43
79 files changed, 1553 insertions, 233 deletions
diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs
index 022051e008e..446c6832cb7 100644
--- a/compiler/rustc_driver/src/pretty.rs
+++ b/compiler/rustc_driver/src/pretty.rs
@@ -498,6 +498,21 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante
             out
         }
 
+        ThirFlat => {
+            let mut out = String::new();
+            abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess);
+            debug!("pretty printing THIR flat");
+            for did in tcx.hir().body_owners() {
+                let _ = writeln!(
+                    out,
+                    "{:?}:\n{}\n",
+                    did,
+                    tcx.thir_flat(ty::WithOptConstParam::unknown(did))
+                );
+            }
+            out
+        }
+
         _ => unreachable!(),
     };
 
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b6481d70bc8..4a38ab2159f 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3531,9 +3531,15 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// Previously, there were very like checks being performed on `#[doc(..)]`
-    /// unlike the other attributes. It'll now catch all the issues that it
-    /// silently ignored previously.
+    /// Previously, incorrect usage of the `#[doc(..)]` attribute was not
+    /// being validated. Usually these should be rejected as a hard error,
+    /// but this lint was introduced to avoid breaking any existing
+    /// crates which included them.
+    ///
+    /// This is a [future-incompatible] lint to transition this to a hard
+    /// error in the future. See [issue #82730] for more details.
+    ///
+    /// [issue #82730]: https://github.com/rust-lang/rust/issues/82730
     pub INVALID_DOC_ATTRIBUTES,
     Warn,
     "detects invalid `#[doc(...)]` attributes",
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3917a97db4f..1f1f4fc95b5 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -361,6 +361,13 @@ rustc_queries! {
         desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
     }
 
+    /// Create a list-like THIR representation for debugging.
+    query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> String {
+        no_hash
+        arena_cache
+        desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+    }
+
     /// Set of all the `DefId`s in this crate that have MIR associated with
     /// them. This includes all the body owners, but also things like struct
     /// constructors.
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 5f320708c84..6f2dac46753 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -29,6 +29,7 @@ use rustc_target::asm::InlineAsmRegOrRegClass;
 use std::fmt;
 use std::ops::Index;
 
+pub mod print;
 pub mod visit;
 
 macro_rules! thir_with_elements {
diff --git a/compiler/rustc_middle/src/thir/print.rs b/compiler/rustc_middle/src/thir/print.rs
new file mode 100644
index 00000000000..60b903e9906
--- /dev/null
+++ b/compiler/rustc_middle/src/thir/print.rs
@@ -0,0 +1,881 @@
+use crate::thir::*;
+use crate::ty::{self, TyCtxt};
+
+use std::fmt::{self, Write};
+
+impl<'tcx> TyCtxt<'tcx> {
+    pub fn thir_tree_representation<'a>(self, thir: &'a Thir<'tcx>) -> String {
+        let mut printer = ThirPrinter::new(thir);
+        printer.print();
+        printer.into_buffer()
+    }
+}
+
+struct ThirPrinter<'a, 'tcx> {
+    thir: &'a Thir<'tcx>,
+    fmt: String,
+}
+
+const INDENT: &str = "    ";
+
+macro_rules! print_indented {
+    ($writer:ident, $s:expr, $indent_lvl:expr) => {
+        let indent = (0..$indent_lvl).map(|_| INDENT).collect::<Vec<_>>().concat();
+        writeln!($writer, "{}{}", indent, $s).expect("unable to write to ThirPrinter");
+    };
+}
+
+impl<'a, 'tcx> Write for ThirPrinter<'a, 'tcx> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.fmt.push_str(s);
+        Ok(())
+    }
+}
+
+impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
+    fn new(thir: &'a Thir<'tcx>) -> Self {
+        Self { thir, fmt: String::new() }
+    }
+
+    fn print(&mut self) {
+        print_indented!(self, "params: [", 0);
+        for param in self.thir.params.iter() {
+            self.print_param(param, 1);
+        }
+        print_indented!(self, "]", 0);
+
+        print_indented!(self, "body:", 0);
+        let expr = ExprId::from_usize(self.thir.exprs.len() - 1);
+        self.print_expr(expr, 1);
+    }
+
+    fn into_buffer(self) -> String {
+        self.fmt
+    }
+
+    fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) {
+        let Param { pat, ty, ty_span, self_kind, hir_id } = param;
+
+        print_indented!(self, "Param {", depth_lvl);
+        print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
+        print_indented!(self, format!("ty_span: {:?}", ty_span), depth_lvl + 1);
+        print_indented!(self, format!("self_kind: {:?}", self_kind), depth_lvl + 1);
+        print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 1);
+
+        if let Some(pat) = pat {
+            print_indented!(self, "param: Some( ", depth_lvl + 1);
+            self.print_pat(pat, depth_lvl + 2);
+            print_indented!(self, ")", depth_lvl + 1);
+        } else {
+            print_indented!(self, "param: None", depth_lvl + 1);
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_block(&mut self, block_id: BlockId, depth_lvl: usize) {
+        let Block {
+            targeted_by_break,
+            opt_destruction_scope,
+            span,
+            region_scope,
+            stmts,
+            expr,
+            safety_mode,
+        } = &self.thir.blocks[block_id];
+
+        print_indented!(self, "Block {", depth_lvl);
+        print_indented!(self, format!("targeted_by_break: {}", targeted_by_break), depth_lvl + 1);
+        print_indented!(
+            self,
+            format!("opt_destruction_scope: {:?}", opt_destruction_scope),
+            depth_lvl + 1
+        );
+        print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+        print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
+        print_indented!(self, format!("safety_mode: {:?}", safety_mode), depth_lvl + 1);
+
+        if stmts.len() > 0 {
+            print_indented!(self, "stmts: [", depth_lvl + 1);
+            for stmt in stmts.iter() {
+                self.print_stmt(*stmt, depth_lvl + 2);
+            }
+            print_indented!(self, "]", depth_lvl + 1);
+        } else {
+            print_indented!(self, "stmts: []", depth_lvl + 1);
+        }
+
+        if let Some(expr_id) = expr {
+            print_indented!(self, "expr:", depth_lvl + 1);
+            self.print_expr(*expr_id, depth_lvl + 2);
+        } else {
+            print_indented!(self, "expr: []", depth_lvl + 1);
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_stmt(&mut self, stmt_id: StmtId, depth_lvl: usize) {
+        let Stmt { kind, opt_destruction_scope } = &self.thir.stmts[stmt_id];
+
+        print_indented!(self, "Stmt {", depth_lvl);
+        print_indented!(
+            self,
+            format!("opt_destruction_scope: {:?}", opt_destruction_scope),
+            depth_lvl + 1
+        );
+
+        match kind {
+            StmtKind::Expr { scope, expr } => {
+                print_indented!(self, "kind: Expr {", depth_lvl + 1);
+                print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 2);
+                print_indented!(self, "expr:", depth_lvl + 2);
+                self.print_expr(*expr, depth_lvl + 3);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            StmtKind::Let {
+                remainder_scope,
+                init_scope,
+                pattern,
+                initializer,
+                else_block,
+                lint_level,
+            } => {
+                print_indented!(self, "kind: Let {", depth_lvl + 1);
+                print_indented!(
+                    self,
+                    format!("remainder_scope: {:?}", remainder_scope),
+                    depth_lvl + 2
+                );
+                print_indented!(self, format!("init_scope: {:?}", init_scope), depth_lvl + 2);
+
+                print_indented!(self, "pattern: ", depth_lvl + 2);
+                self.print_pat(pattern, depth_lvl + 3);
+                print_indented!(self, ",", depth_lvl + 2);
+
+                if let Some(init) = initializer {
+                    print_indented!(self, "initializer: Some(", depth_lvl + 2);
+                    self.print_expr(*init, depth_lvl + 3);
+                    print_indented!(self, ")", depth_lvl + 2);
+                } else {
+                    print_indented!(self, "initializer: None", depth_lvl + 2);
+                }
+
+                if let Some(else_block) = else_block {
+                    print_indented!(self, "else_block: Some(", depth_lvl + 2);
+                    self.print_block(*else_block, depth_lvl + 3);
+                    print_indented!(self, ")", depth_lvl + 2);
+                } else {
+                    print_indented!(self, "else_block: None", depth_lvl + 2);
+                }
+
+                print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_expr(&mut self, expr: ExprId, depth_lvl: usize) {
+        let Expr { ty, temp_lifetime, span, kind } = &self.thir[expr];
+        print_indented!(self, "Expr {", depth_lvl);
+        print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
+        print_indented!(self, format!("temp_lifetime: {:?}", temp_lifetime), depth_lvl + 1);
+        print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+        print_indented!(self, "kind: ", depth_lvl + 1);
+        self.print_expr_kind(kind, depth_lvl + 2);
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
+        use rustc_middle::thir::ExprKind::*;
+
+        match expr_kind {
+            Scope { region_scope, value, lint_level } => {
+                print_indented!(self, "Scope {", depth_lvl);
+                print_indented!(self, format!("region_scope: {:?}", region_scope), depth_lvl + 1);
+                print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
+                print_indented!(self, "value:", depth_lvl + 1);
+                self.print_expr(*value, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Box { value } => {
+                print_indented!(self, "Box {", depth_lvl);
+                self.print_expr(*value, depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            If { if_then_scope, cond, then, else_opt } => {
+                print_indented!(self, "If {", depth_lvl);
+                print_indented!(self, format!("if_then_scope: {:?}", if_then_scope), depth_lvl + 1);
+                print_indented!(self, "cond:", depth_lvl + 1);
+                self.print_expr(*cond, depth_lvl + 2);
+                print_indented!(self, "then:", depth_lvl + 1);
+                self.print_expr(*then, depth_lvl + 2);
+
+                if let Some(else_expr) = else_opt {
+                    print_indented!(self, "else:", depth_lvl + 1);
+                    self.print_expr(*else_expr, depth_lvl + 2);
+                }
+
+                print_indented!(self, "}", depth_lvl);
+            }
+            Call { fun, args, ty, from_hir_call, fn_span } => {
+                print_indented!(self, "Call {", depth_lvl);
+                print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
+                print_indented!(self, format!("from_hir_call: {}", from_hir_call), depth_lvl + 1);
+                print_indented!(self, format!("fn_span: {:?}", fn_span), depth_lvl + 1);
+                print_indented!(self, "fun:", depth_lvl + 1);
+                self.print_expr(*fun, depth_lvl + 2);
+
+                if args.len() > 0 {
+                    print_indented!(self, "args: [", depth_lvl + 1);
+                    for arg in args.iter() {
+                        self.print_expr(*arg, depth_lvl + 2);
+                    }
+                    print_indented!(self, "]", depth_lvl + 1);
+                } else {
+                    print_indented!(self, "args: []", depth_lvl + 1);
+                }
+
+                print_indented!(self, "}", depth_lvl);
+            }
+            Deref { arg } => {
+                print_indented!(self, "Deref {", depth_lvl);
+                self.print_expr(*arg, depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Binary { op, lhs, rhs } => {
+                print_indented!(self, "Binary {", depth_lvl);
+                print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "rhs:", depth_lvl + 1);
+                self.print_expr(*rhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            LogicalOp { op, lhs, rhs } => {
+                print_indented!(self, "LogicalOp {", depth_lvl);
+                print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "rhs:", depth_lvl + 1);
+                self.print_expr(*rhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Unary { op, arg } => {
+                print_indented!(self, "Unary {", depth_lvl);
+                print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
+                print_indented!(self, "arg:", depth_lvl + 1);
+                self.print_expr(*arg, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Cast { source } => {
+                print_indented!(self, "Cast {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Use { source } => {
+                print_indented!(self, "Use {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            NeverToAny { source } => {
+                print_indented!(self, "NeverToAny {", depth_lvl);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Pointer { cast, source } => {
+                print_indented!(self, "Pointer {", depth_lvl);
+                print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Loop { body } => {
+                print_indented!(self, "Loop (", depth_lvl);
+                print_indented!(self, "body:", depth_lvl + 1);
+                self.print_expr(*body, depth_lvl + 2);
+                print_indented!(self, ")", depth_lvl);
+            }
+            Let { expr, pat } => {
+                print_indented!(self, "Let {", depth_lvl);
+                print_indented!(self, "expr:", depth_lvl + 1);
+                self.print_expr(*expr, depth_lvl + 2);
+                print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Match { scrutinee, arms } => {
+                print_indented!(self, "Match {", depth_lvl);
+                print_indented!(self, "scrutinee:", depth_lvl + 1);
+                self.print_expr(*scrutinee, depth_lvl + 2);
+
+                print_indented!(self, "arms: [", depth_lvl + 1);
+                for arm_id in arms.iter() {
+                    self.print_arm(*arm_id, depth_lvl + 2);
+                }
+                print_indented!(self, "]", depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Block { block } => self.print_block(*block, depth_lvl),
+            Assign { lhs, rhs } => {
+                print_indented!(self, "Assign {", depth_lvl);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "rhs:", depth_lvl + 1);
+                self.print_expr(*rhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            AssignOp { op, lhs, rhs } => {
+                print_indented!(self, "AssignOp {", depth_lvl);
+                print_indented!(self, format!("op: {:?}", op), depth_lvl + 1);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "rhs:", depth_lvl + 1);
+                self.print_expr(*rhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Field { lhs, variant_index, name } => {
+                print_indented!(self, "Field {", depth_lvl);
+                print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 1);
+                print_indented!(self, format!("name: {:?}", name), depth_lvl + 1);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Index { lhs, index } => {
+                print_indented!(self, "Index {", depth_lvl);
+                print_indented!(self, format!("index: {:?}", index), depth_lvl + 1);
+                print_indented!(self, "lhs:", depth_lvl + 1);
+                self.print_expr(*lhs, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            VarRef { id } => {
+                print_indented!(self, "VarRef {", depth_lvl);
+                print_indented!(self, format!("id: {:?}", id), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            UpvarRef { closure_def_id, var_hir_id } => {
+                print_indented!(self, "UpvarRef {", depth_lvl);
+                print_indented!(
+                    self,
+                    format!("closure_def_id: {:?}", closure_def_id),
+                    depth_lvl + 1
+                );
+                print_indented!(self, format!("var_hir_id: {:?}", var_hir_id), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Borrow { borrow_kind, arg } => {
+                print_indented!(self, "Borrow (", depth_lvl);
+                print_indented!(self, format!("borrow_kind: {:?}", borrow_kind), depth_lvl + 1);
+                print_indented!(self, "arg:", depth_lvl + 1);
+                self.print_expr(*arg, depth_lvl + 2);
+                print_indented!(self, ")", depth_lvl);
+            }
+            AddressOf { mutability, arg } => {
+                print_indented!(self, "AddressOf {", depth_lvl);
+                print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 1);
+                print_indented!(self, "arg:", depth_lvl + 1);
+                self.print_expr(*arg, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Break { label, value } => {
+                print_indented!(self, "Break (", depth_lvl);
+                print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
+
+                if let Some(value) = value {
+                    print_indented!(self, "value:", depth_lvl + 1);
+                    self.print_expr(*value, depth_lvl + 2);
+                }
+
+                print_indented!(self, ")", depth_lvl);
+            }
+            Continue { label } => {
+                print_indented!(self, "Continue {", depth_lvl);
+                print_indented!(self, format!("label: {:?}", label), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Return { value } => {
+                print_indented!(self, "Return {", depth_lvl);
+                print_indented!(self, "value:", depth_lvl + 1);
+
+                if let Some(value) = value {
+                    self.print_expr(*value, depth_lvl + 2);
+                }
+
+                print_indented!(self, "}", depth_lvl);
+            }
+            ConstBlock { did, substs } => {
+                print_indented!(self, "ConstBlock {", depth_lvl);
+                print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
+                print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Repeat { value, count } => {
+                print_indented!(self, "Repeat {", depth_lvl);
+                print_indented!(self, format!("count: {:?}", count), depth_lvl + 1);
+                print_indented!(self, "value:", depth_lvl + 1);
+                self.print_expr(*value, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Array { fields } => {
+                print_indented!(self, "Array {", depth_lvl);
+                print_indented!(self, "fields: [", depth_lvl + 1);
+                for field_id in fields.iter() {
+                    self.print_expr(*field_id, depth_lvl + 2);
+                }
+                print_indented!(self, "]", depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Tuple { fields } => {
+                print_indented!(self, "Tuple {", depth_lvl);
+                print_indented!(self, "fields: [", depth_lvl + 1);
+                for field_id in fields.iter() {
+                    self.print_expr(*field_id, depth_lvl + 2);
+                }
+                print_indented!(self, "]", depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Adt(adt_expr) => {
+                print_indented!(self, "Adt {", depth_lvl);
+                self.print_adt_expr(&**adt_expr, depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            PlaceTypeAscription { source, user_ty } => {
+                print_indented!(self, "PlaceTypeAscription {", depth_lvl);
+                print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ValueTypeAscription { source, user_ty } => {
+                print_indented!(self, "ValueTypeAscription {", depth_lvl);
+                print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
+                print_indented!(self, "source:", depth_lvl + 1);
+                self.print_expr(*source, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Closure(closure_expr) => {
+                print_indented!(self, "Closure {", depth_lvl);
+                print_indented!(self, "closure_expr:", depth_lvl + 1);
+                self.print_closure_expr(&**closure_expr, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Literal { lit, neg } => {
+                print_indented!(
+                    self,
+                    format!("Literal( lit: {:?}, neg: {:?})\n", lit, neg),
+                    depth_lvl
+                );
+            }
+            NonHirLiteral { lit, user_ty } => {
+                print_indented!(self, "NonHirLiteral {", depth_lvl);
+                print_indented!(self, format!("lit: {:?}", lit), depth_lvl + 1);
+                print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ZstLiteral { user_ty } => {
+                print_indented!(self, format!("ZstLiteral(user_ty: {:?})", user_ty), depth_lvl);
+            }
+            NamedConst { def_id, substs, user_ty } => {
+                print_indented!(self, "NamedConst {", depth_lvl);
+                print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
+                print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
+                print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ConstParam { param, def_id } => {
+                print_indented!(self, "ConstParam {", depth_lvl);
+                print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
+                print_indented!(self, format!("param: {:?}", param), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            StaticRef { alloc_id, ty, def_id } => {
+                print_indented!(self, "StaticRef {", depth_lvl);
+                print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
+                print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
+                print_indented!(self, format!("alloc_id: {:?}", alloc_id), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            InlineAsm(expr) => {
+                print_indented!(self, "InlineAsm {", depth_lvl);
+                print_indented!(self, "expr:", depth_lvl + 1);
+                self.print_inline_asm_expr(&**expr, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+            ThreadLocalRef(def_id) => {
+                print_indented!(self, "ThreadLocalRef {", depth_lvl);
+                print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl);
+            }
+            Yield { value } => {
+                print_indented!(self, "Yield {", depth_lvl);
+                print_indented!(self, "value:", depth_lvl + 1);
+                self.print_expr(*value, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl);
+            }
+        }
+    }
+
+    fn print_adt_expr(&mut self, adt_expr: &AdtExpr<'tcx>, depth_lvl: usize) {
+        print_indented!(self, "adt_def:", depth_lvl);
+        self.print_adt_def(adt_expr.adt_def, depth_lvl + 1);
+        print_indented!(
+            self,
+            format!("variant_index: {:?}", adt_expr.variant_index),
+            depth_lvl + 1
+        );
+        print_indented!(self, format!("substs: {:?}", adt_expr.substs), depth_lvl + 1);
+        print_indented!(self, format!("user_ty: {:?}", adt_expr.user_ty), depth_lvl + 1);
+
+        for (i, field_expr) in adt_expr.fields.iter().enumerate() {
+            print_indented!(self, format!("field {}:", i), depth_lvl + 1);
+            self.print_expr(field_expr.expr, depth_lvl + 2);
+        }
+
+        if let Some(ref base) = adt_expr.base {
+            print_indented!(self, "base:", depth_lvl + 1);
+            self.print_fru_info(base, depth_lvl + 2);
+        } else {
+            print_indented!(self, "base: None", depth_lvl + 1);
+        }
+    }
+
+    fn print_adt_def(&mut self, adt_def: ty::AdtDef<'tcx>, depth_lvl: usize) {
+        print_indented!(self, "AdtDef {", depth_lvl);
+        print_indented!(self, format!("did: {:?}", adt_def.did()), depth_lvl + 1);
+        print_indented!(self, format!("variants: {:?}", adt_def.variants()), depth_lvl + 1);
+        print_indented!(self, format!("flags: {:?}", adt_def.flags()), depth_lvl + 1);
+        print_indented!(self, format!("repr: {:?}", adt_def.repr()), depth_lvl + 1);
+    }
+
+    fn print_fru_info(&mut self, fru_info: &FruInfo<'tcx>, depth_lvl: usize) {
+        print_indented!(self, "FruInfo {", depth_lvl);
+        print_indented!(self, "base: ", depth_lvl + 1);
+        self.print_expr(fru_info.base, depth_lvl + 2);
+        print_indented!(self, "field_types: [", depth_lvl + 1);
+        for ty in fru_info.field_types.iter() {
+            print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
+        }
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_arm(&mut self, arm_id: ArmId, depth_lvl: usize) {
+        print_indented!(self, "Arm {", depth_lvl);
+
+        let arm = &self.thir.arms[arm_id];
+        let Arm { pattern, guard, body, lint_level, scope, span } = arm;
+
+        print_indented!(self, "pattern: ", depth_lvl + 1);
+        self.print_pat(pattern, depth_lvl + 2);
+
+        if let Some(guard) = guard {
+            print_indented!(self, "guard: ", depth_lvl + 1);
+            self.print_guard(guard, depth_lvl + 2);
+        } else {
+            print_indented!(self, "guard: None", depth_lvl + 1);
+        }
+
+        print_indented!(self, "body: ", depth_lvl + 1);
+        self.print_expr(*body, depth_lvl + 2);
+        print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
+        print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 1);
+        print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_pat(&mut self, pat: &Box<Pat<'tcx>>, depth_lvl: usize) {
+        let Pat { ty, span, kind } = &**pat;
+
+        print_indented!(self, "Pat: {", depth_lvl);
+        print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
+        print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+        self.print_pat_kind(kind, depth_lvl + 1);
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
+        print_indented!(self, "kind: PatKind {", depth_lvl);
+
+        match pat_kind {
+            PatKind::Wild => {
+                print_indented!(self, "Wild", depth_lvl + 1);
+            }
+            PatKind::AscribeUserType { ascription, subpattern } => {
+                print_indented!(self, "AscribeUserType: {", depth_lvl + 1);
+                print_indented!(self, format!("ascription: {:?}", ascription), depth_lvl + 2);
+                print_indented!(self, "subpattern: ", depth_lvl + 2);
+                self.print_pat(subpattern, depth_lvl + 3);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Binding { mutability, name, mode, var, ty, subpattern, is_primary } => {
+                print_indented!(self, "Binding {", depth_lvl + 1);
+                print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 2);
+                print_indented!(self, format!("name: {:?}", name), depth_lvl + 2);
+                print_indented!(self, format!("mode: {:?}", mode), depth_lvl + 2);
+                print_indented!(self, format!("var: {:?}", var), depth_lvl + 2);
+                print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 2);
+                print_indented!(self, format!("is_primary: {:?}", is_primary), depth_lvl + 2);
+
+                if let Some(subpattern) = subpattern {
+                    print_indented!(self, "subpattern: Some( ", depth_lvl + 2);
+                    self.print_pat(subpattern, depth_lvl + 3);
+                    print_indented!(self, ")", depth_lvl + 2);
+                } else {
+                    print_indented!(self, "subpattern: None", depth_lvl + 2);
+                }
+
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Variant { adt_def, substs, variant_index, subpatterns } => {
+                print_indented!(self, "Variant {", depth_lvl + 1);
+                print_indented!(self, "adt_def: ", depth_lvl + 2);
+                self.print_adt_def(*adt_def, depth_lvl + 3);
+                print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 2);
+                print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 2);
+
+                if subpatterns.len() > 0 {
+                    print_indented!(self, "subpatterns: [", depth_lvl + 2);
+                    for field_pat in subpatterns.iter() {
+                        self.print_pat(&field_pat.pattern, depth_lvl + 3);
+                    }
+                    print_indented!(self, "]", depth_lvl + 2);
+                } else {
+                    print_indented!(self, "subpatterns: []", depth_lvl + 2);
+                }
+
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Leaf { subpatterns } => {
+                print_indented!(self, "Leaf { ", depth_lvl + 1);
+                print_indented!(self, "subpatterns: [", depth_lvl + 2);
+                for field_pat in subpatterns.iter() {
+                    self.print_pat(&field_pat.pattern, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Deref { subpattern } => {
+                print_indented!(self, "Deref { ", depth_lvl + 1);
+                print_indented!(self, "subpattern: ", depth_lvl + 2);
+                self.print_pat(subpattern, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Constant { value } => {
+                print_indented!(self, "Constant {", depth_lvl + 1);
+                print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Range(pat_range) => {
+                print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1);
+            }
+            PatKind::Slice { prefix, slice, suffix } => {
+                print_indented!(self, "Slice {", depth_lvl + 1);
+
+                print_indented!(self, "prefix: [", depth_lvl + 2);
+                for prefix_pat in prefix.iter() {
+                    self.print_pat(prefix_pat, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+
+                if let Some(slice) = slice {
+                    print_indented!(self, "slice: ", depth_lvl + 2);
+                    self.print_pat(slice, depth_lvl + 3);
+                }
+
+                print_indented!(self, "suffix: [", depth_lvl + 2);
+                for suffix_pat in suffix.iter() {
+                    self.print_pat(suffix_pat, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Array { prefix, slice, suffix } => {
+                print_indented!(self, "Array {", depth_lvl + 1);
+
+                print_indented!(self, "prefix: [", depth_lvl + 2);
+                for prefix_pat in prefix.iter() {
+                    self.print_pat(prefix_pat, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+
+                if let Some(slice) = slice {
+                    print_indented!(self, "slice: ", depth_lvl + 2);
+                    self.print_pat(slice, depth_lvl + 3);
+                }
+
+                print_indented!(self, "suffix: [", depth_lvl + 2);
+                for suffix_pat in suffix.iter() {
+                    self.print_pat(suffix_pat, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            PatKind::Or { pats } => {
+                print_indented!(self, "Or {", depth_lvl + 1);
+                print_indented!(self, "pats: [", depth_lvl + 2);
+                for pat in pats.iter() {
+                    self.print_pat(pat, depth_lvl + 3);
+                }
+                print_indented!(self, "]", depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_guard(&mut self, guard: &Guard<'tcx>, depth_lvl: usize) {
+        print_indented!(self, "Guard {", depth_lvl);
+
+        match guard {
+            Guard::If(expr_id) => {
+                print_indented!(self, "If (", depth_lvl + 1);
+                self.print_expr(*expr_id, depth_lvl + 2);
+                print_indented!(self, ")", depth_lvl + 1);
+            }
+            Guard::IfLet(pat, expr_id) => {
+                print_indented!(self, "IfLet (", depth_lvl + 1);
+                self.print_pat(pat, depth_lvl + 2);
+                print_indented!(self, ",", depth_lvl + 1);
+                self.print_expr(*expr_id, depth_lvl + 2);
+                print_indented!(self, ")", depth_lvl + 1);
+            }
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
+        let ClosureExpr { closure_id, substs, upvars, movability, fake_reads } = expr;
+
+        print_indented!(self, "ClosureExpr {", depth_lvl);
+        print_indented!(self, format!("closure_id: {:?}", closure_id), depth_lvl + 1);
+        print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+
+        if upvars.len() > 0 {
+            print_indented!(self, "upvars: [", depth_lvl + 1);
+            for upvar in upvars.iter() {
+                self.print_expr(*upvar, depth_lvl + 2);
+                print_indented!(self, ",", depth_lvl + 1);
+            }
+            print_indented!(self, "]", depth_lvl + 1);
+        } else {
+            print_indented!(self, "upvars: []", depth_lvl + 1);
+        }
+
+        print_indented!(self, format!("movability: {:?}", movability), depth_lvl + 1);
+
+        if fake_reads.len() > 0 {
+            print_indented!(self, "fake_reads: [", depth_lvl + 1);
+            for (fake_read_expr, cause, hir_id) in fake_reads.iter() {
+                print_indented!(self, "(", depth_lvl + 2);
+                self.print_expr(*fake_read_expr, depth_lvl + 3);
+                print_indented!(self, ",", depth_lvl + 2);
+                print_indented!(self, format!("cause: {:?}", cause), depth_lvl + 3);
+                print_indented!(self, ",", depth_lvl + 2);
+                print_indented!(self, format!("hir_id: {:?}", hir_id), depth_lvl + 3);
+                print_indented!(self, "),", depth_lvl + 2);
+            }
+            print_indented!(self, "]", depth_lvl + 1);
+        } else {
+            print_indented!(self, "fake_reads: []", depth_lvl + 1);
+        }
+
+        print_indented!(self, "}", depth_lvl);
+    }
+
+    fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
+        let InlineAsmExpr { template, operands, options, line_spans } = expr;
+
+        print_indented!(self, "InlineAsmExpr {", depth_lvl);
+
+        print_indented!(self, "template: [", depth_lvl + 1);
+        for template_piece in template.iter() {
+            print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);
+        }
+        print_indented!(self, "]", depth_lvl + 1);
+
+        print_indented!(self, "operands: [", depth_lvl + 1);
+        for operand in operands.iter() {
+            self.print_inline_operand(operand, depth_lvl + 2);
+        }
+        print_indented!(self, "]", depth_lvl + 1);
+
+        print_indented!(self, format!("options: {:?}", options), depth_lvl + 1);
+        print_indented!(self, format!("line_spans: {:?}", line_spans), depth_lvl + 1);
+    }
+
+    fn print_inline_operand(&mut self, operand: &InlineAsmOperand<'tcx>, depth_lvl: usize) {
+        match operand {
+            InlineAsmOperand::In { reg, expr } => {
+                print_indented!(self, "InlineAsmOperand::In {", depth_lvl);
+                print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
+                print_indented!(self, "expr: ", depth_lvl + 1);
+                self.print_expr(*expr, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::Out { reg, late, expr } => {
+                print_indented!(self, "InlineAsmOperand::Out {", depth_lvl);
+                print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
+                print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
+
+                if let Some(out) = expr {
+                    print_indented!(self, "place: Some( ", depth_lvl + 1);
+                    self.print_expr(*out, depth_lvl + 2);
+                    print_indented!(self, ")", depth_lvl + 1);
+                } else {
+                    print_indented!(self, "place: None", depth_lvl + 1);
+                }
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::InOut { reg, late, expr } => {
+                print_indented!(self, "InlineAsmOperand::InOut {", depth_lvl);
+                print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
+                print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
+                print_indented!(self, "expr: ", depth_lvl + 1);
+                self.print_expr(*expr, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
+                print_indented!(self, "InlineAsmOperand::SplitInOut {", depth_lvl);
+                print_indented!(self, format!("reg: {:?}", reg), depth_lvl + 1);
+                print_indented!(self, format!("late: {:?}", late), depth_lvl + 1);
+                print_indented!(self, "in_expr: ", depth_lvl + 1);
+                self.print_expr(*in_expr, depth_lvl + 2);
+
+                if let Some(out_expr) = out_expr {
+                    print_indented!(self, "out_expr: Some( ", depth_lvl + 1);
+                    self.print_expr(*out_expr, depth_lvl + 2);
+                    print_indented!(self, ")", depth_lvl + 1);
+                } else {
+                    print_indented!(self, "out_expr: None", depth_lvl + 1);
+                }
+
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::Const { value, span } => {
+                print_indented!(self, "InlineAsmOperand::Const {", depth_lvl);
+                print_indented!(self, format!("value: {:?}", value), depth_lvl + 1);
+                print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::SymFn { value, span } => {
+                print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl);
+                print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1);
+                print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+            InlineAsmOperand::SymStatic { def_id } => {
+                print_indented!(self, "InlineAsmOperand::SymStatic {", depth_lvl);
+                print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index f85831b4fc6..1655e224ddb 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -439,6 +439,10 @@ fn construct_fn<'tcx>(
     let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
     let generator_kind = tcx.generator_kind(fn_def.did);
 
+    // The representation of thir for `-Zunpretty=thir-tree` relies on
+    // the entry expression being the last element of `thir.exprs`.
+    assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
+
     // Figure out what primary body this item has.
     let body_id = tcx.hir().body_owned_by(fn_def.did);
     let span_with_body = tcx.hir().span_with_body(fn_id);
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index a428180a4fa..94dae36154c 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -34,4 +34,5 @@ pub fn provide(providers: &mut Providers) {
     providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
     providers.thir_body = thir::cx::thir_body;
     providers.thir_tree = thir::cx::thir_tree;
+    providers.thir_flat = thir::cx::thir_flat;
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index a355e1bdab5..10df4b22952 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -54,6 +54,16 @@ pub(crate) fn thir_body(
 
 pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
     match thir_body(tcx, owner_def) {
+        Ok((thir, _)) => {
+            let thir = thir.steal();
+            tcx.thir_tree_representation(&thir)
+        }
+        Err(_) => "error".into(),
+    }
+}
+
+pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String {
+    match thir_body(tcx, owner_def) {
         Ok((thir, _)) => format!("{:#?}", thir.steal()),
         Err(_) => "error".into(),
     }
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 25de0a9e750..82d9138c7a3 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1048,7 +1048,7 @@ impl<'a> Parser<'a> {
                 self.parse_remaining_bounds(bounds, true)?;
                 self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
                 let sp = vec![lo, self.prev_token.span];
-                let sugg: Vec<_> = sp.iter().map(|sp| (*sp, String::new())).collect();
+                let sugg = vec![(lo, String::from(" ")), (self.prev_token.span, String::new())];
                 self.struct_span_err(sp, "incorrect braces around trait bounds")
                     .multipart_suggestion(
                         "remove the parentheses",
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index db95b8bca2f..c49c5fa9904 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2573,6 +2573,7 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
         "hir,typed" => Hir(PpHirMode::Typed),
         "hir-tree" => HirTree,
         "thir-tree" => ThirTree,
+        "thir-flat" => ThirFlat,
         "mir" => Mir,
         "mir-cfg" => MirCFG,
         name => early_error(
@@ -2581,7 +2582,8 @@ fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> Optio
                 "argument to `unpretty` must be one of `normal`, `identified`, \
                             `expanded`, `expanded,identified`, `expanded,hygiene`, \
                             `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
-                            `hir,typed`, `hir-tree`, `thir-tree`, `mir` or `mir-cfg`; got {name}"
+                            `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir` or \
+                            `mir-cfg`; got {name}"
             ),
         ),
     };
@@ -2736,6 +2738,8 @@ pub enum PpMode {
     HirTree,
     /// `-Zunpretty=thir-tree`
     ThirTree,
+    /// `-Zunpretty=`thir-flat`
+    ThirFlat,
     /// `-Zunpretty=mir`
     Mir,
     /// `-Zunpretty=mir-cfg`
@@ -2754,6 +2758,7 @@ impl PpMode {
             | Hir(_)
             | HirTree
             | ThirTree
+            | ThirFlat
             | Mir
             | MirCFG => true,
         }
@@ -2763,13 +2768,13 @@ impl PpMode {
         match *self {
             Source(_) | AstTree(_) => false,
 
-            Hir(_) | HirTree | ThirTree | Mir | MirCFG => true,
+            Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
         }
     }
 
     pub fn needs_analysis(&self) -> bool {
         use PpMode::*;
-        matches!(*self, Mir | MirCFG | ThirTree)
+        matches!(*self, Mir | MirCFG | ThirTree | ThirFlat)
     }
 }
 
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 2cae98b8e49..acd0fea4bc4 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2574,12 +2574,13 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
+        #[rustc_allow_const_fn_unstable(const_cmp)]
         pub const fn signum(self) -> Self {
-            match self {
-                n if n > 0 =>  1,
-                0          =>  0,
-                _          => -1,
-            }
+            // Picking the right way to phrase this is complicated
+            // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>)
+            // so delegate it to `Ord` which is already producing -1/0/+1
+            // exactly like we need and can be the place to deal with the complexity.
+            self.cmp(&0) as _
         }
 
         /// Returns `true` if `self` is positive and `false` if the number is zero or
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index ecd06ebf743..acf9c29083f 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -1,6 +1,6 @@
 //! Temporal quantification.
 //!
-//! # Examples:
+//! # Examples
 //!
 //! There are multiple ways to create a new [`Duration`]:
 //!
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 24cbe035f2f..1ee68c8540b 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -53,6 +53,7 @@ pub struct ConsoleTestState {
     pub metrics: MetricMap,
     pub failures: Vec<(TestDesc, Vec<u8>)>,
     pub not_failures: Vec<(TestDesc, Vec<u8>)>,
+    pub ignores: Vec<(TestDesc, Vec<u8>)>,
     pub time_failures: Vec<(TestDesc, Vec<u8>)>,
     pub options: Options,
 }
@@ -76,6 +77,7 @@ impl ConsoleTestState {
             metrics: MetricMap::new(),
             failures: Vec::new(),
             not_failures: Vec::new(),
+            ignores: Vec::new(),
             time_failures: Vec::new(),
             options: opts.options,
         })
@@ -194,7 +196,10 @@ fn handle_test_result(st: &mut ConsoleTestState, completed_test: CompletedTest)
             st.passed += 1;
             st.not_failures.push((test, stdout));
         }
-        TestResult::TrIgnored => st.ignored += 1,
+        TestResult::TrIgnored => {
+            st.ignored += 1;
+            st.ignores.push((test, stdout));
+        }
         TestResult::TrBench(bs) => {
             st.metrics.insert_metric(
                 test.name.as_slice(),
diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs
index 0837ab16905..a431acfbc27 100644
--- a/library/test/src/formatters/terse.rs
+++ b/library/test/src/formatters/terse.rs
@@ -254,6 +254,15 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
 
         self.write_plain("\n\n")?;
 
+        // Custom handling of cases where there is only 1 test to execute and that test was ignored.
+        // We want to show more detailed information(why was the test ignored) for investigation purposes.
+        if self.total_test_count == 1 && state.ignores.len() == 1 {
+            let test_desc = &state.ignores[0].0;
+            if let Some(im) = test_desc.ignore_message {
+                self.write_plain(format!("test: {}, ignore_message: {}\n\n", test_desc.name, im))?;
+            }
+        }
+
         Ok(success)
     }
 }
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 3a0260f86cf..44776fb0a31 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -790,6 +790,7 @@ fn should_sort_failures_before_printing_them() {
         failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
         options: Options::new(),
         not_failures: Vec::new(),
+        ignores: Vec::new(),
         time_failures: Vec::new(),
     };
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 522b3b7e851..3b9dba4109d 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1433,7 +1433,8 @@ impl Build {
 
         if !stamp.exists() {
             eprintln!(
-                "Warning: Unable to find the stamp file, did you try to keep a nonexistent build stage?"
+                "Error: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?",
+                stamp.display()
             );
             crate::detail_exit(1);
         }
diff --git a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh
index c6d728eb80d..0b06f5e3623 100755
--- a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh
+++ b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh
@@ -9,11 +9,5 @@ git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
 cd rust-toolstate
 python3 "../../src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \
     "$(git log --format=%s -n1 HEAD)" "" ""
-# Only check maintainers if this build is supposed to publish toolstate.
-# Builds that are not supposed to publish don't have the access token.
-if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
-  TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python3 \
-      "../../src/tools/publish_toolstate.py"
-fi
 cd ..
 rm -rf rust-toolstate
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index 7a846d44ad6..ff17931115c 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -14,4 +14,4 @@ ROOT_DIR="$(git rev-parse --show-toplevel)"
 echo "Running pre-push script $ROOT_DIR/x test tidy"
 
 cd "$ROOT_DIR"
-./x test tidy
+CARGOFLAGS="--locked" ./x test tidy
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index d644293d3ef..be6de231854 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1528,11 +1528,7 @@ fn render_impl(
                             })
                         })
                         .map(|item| format!("{}.{}", item.type_(), name));
-                    write!(
-                        w,
-                        "<section id=\"{}\" class=\"{}{} has-srclink\">",
-                        id, item_type, in_trait_class,
-                    );
+                    write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class,);
                     render_rightside(w, cx, item, containing_item, render_mode);
                     if trait_.is_some() {
                         // Anchors are only used on trait impls.
@@ -1554,11 +1550,7 @@ fn render_impl(
             kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => {
                 let source_id = format!("{}.{}", item_type, name);
                 let id = cx.derive_id(source_id.clone());
-                write!(
-                    w,
-                    "<section id=\"{}\" class=\"{}{} has-srclink\">",
-                    id, item_type, in_trait_class
-                );
+                write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class);
                 render_rightside(w, cx, item, containing_item, render_mode);
                 if trait_.is_some() {
                     // Anchors are only used on trait impls.
@@ -1606,11 +1598,7 @@ fn render_impl(
             clean::AssocTypeItem(tydef, _bounds) => {
                 let source_id = format!("{}.{}", item_type, name);
                 let id = cx.derive_id(source_id.clone());
-                write!(
-                    w,
-                    "<section id=\"{}\" class=\"{}{} has-srclink\">",
-                    id, item_type, in_trait_class
-                );
+                write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class);
                 if trait_.is_some() {
                     // Anchors are only used on trait impls.
                     write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
@@ -1844,7 +1832,7 @@ pub(crate) fn render_impl_summary(
     } else {
         format!(" data-aliases=\"{}\"", aliases.join(","))
     };
-    write!(w, "<section id=\"{}\" class=\"impl has-srclink\"{}>", id, aliases);
+    write!(w, "<section id=\"{}\" class=\"impl\"{}>", id, aliases);
     render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal);
     write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
     write!(w, "<h3 class=\"code-header\">");
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 508b2bab0eb..b0288d55c25 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -735,7 +735,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
             let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
             write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>");
         }
-        write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id);
+        write!(w, "<section id=\"{}\" class=\"method\">", id);
         render_rightside(w, cx, m, t, RenderMode::Normal);
         write!(w, "<h4 class=\"code-header\">");
         render_assoc_item(
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index dc30e4bb1be..45fd87bea9b 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -926,7 +926,7 @@ pub fn make_test_description<R: Read>(
     cfg: Option<&str>,
 ) -> test::TestDesc {
     let mut ignore = false;
-    let ignore_message = None;
+    let mut ignore_message = None;
     let mut should_fail = false;
 
     let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
@@ -966,41 +966,67 @@ pub fn make_test_description<R: Read>(
         if revision.is_some() && revision != cfg {
             return;
         }
+        macro_rules! reason {
+            ($e:expr) => {
+                ignore |= match $e {
+                    true => {
+                        ignore_message = Some(stringify!($e));
+                        true
+                    }
+                    false => ignore,
+                }
+            };
+        }
         ignore = match config.parse_cfg_name_directive(ln, "ignore") {
-            ParsedNameDirective::Match => true,
+            ParsedNameDirective::Match => {
+                ignore_message = Some("cfg -> ignore => Match");
+                true
+            }
             ParsedNameDirective::NoMatch => ignore,
         };
+
         if config.has_cfg_prefix(ln, "only") {
             ignore = match config.parse_cfg_name_directive(ln, "only") {
                 ParsedNameDirective::Match => ignore,
-                ParsedNameDirective::NoMatch => true,
+                ParsedNameDirective::NoMatch => {
+                    ignore_message = Some("cfg -> only => NoMatch");
+                    true
+                }
             };
         }
-        ignore |= ignore_llvm(config, ln);
-        ignore |=
-            config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln);
-        ignore |= !has_asm_support && config.parse_name_directive(ln, "needs-asm-support");
-        ignore |= !rustc_has_profiler_support && config.parse_needs_profiler_support(ln);
-        ignore |= !config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled");
-        ignore |= !rustc_has_sanitizer_support
-            && config.parse_name_directive(ln, "needs-sanitizer-support");
-        ignore |= !has_asan && config.parse_name_directive(ln, "needs-sanitizer-address");
-        ignore |= !has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi");
-        ignore |= !has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi");
-        ignore |= !has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak");
-        ignore |= !has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory");
-        ignore |= !has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread");
-        ignore |= !has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress");
-        ignore |= !has_memtag && config.parse_name_directive(ln, "needs-sanitizer-memtag");
-        ignore |= !has_shadow_call_stack
-            && config.parse_name_directive(ln, "needs-sanitizer-shadow-call-stack");
-        ignore |= !config.can_unwind() && config.parse_name_directive(ln, "needs-unwind");
-        ignore |= config.target == "wasm32-unknown-unknown"
-            && config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS);
-        ignore |= config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln);
-        ignore |= config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln);
-        ignore |= config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln);
-        ignore |= !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld");
+
+        reason!(ignore_llvm(config, ln));
+        reason!(
+            config.run_clang_based_tests_with.is_none() && config.parse_needs_matching_clang(ln)
+        );
+        reason!(!has_asm_support && config.parse_name_directive(ln, "needs-asm-support"));
+        reason!(!rustc_has_profiler_support && config.parse_needs_profiler_support(ln));
+        reason!(!config.run_enabled() && config.parse_name_directive(ln, "needs-run-enabled"));
+        reason!(
+            !rustc_has_sanitizer_support
+                && config.parse_name_directive(ln, "needs-sanitizer-support")
+        );
+        reason!(!has_asan && config.parse_name_directive(ln, "needs-sanitizer-address"));
+        reason!(!has_cfi && config.parse_name_directive(ln, "needs-sanitizer-cfi"));
+        reason!(!has_kcfi && config.parse_name_directive(ln, "needs-sanitizer-kcfi"));
+        reason!(!has_lsan && config.parse_name_directive(ln, "needs-sanitizer-leak"));
+        reason!(!has_msan && config.parse_name_directive(ln, "needs-sanitizer-memory"));
+        reason!(!has_tsan && config.parse_name_directive(ln, "needs-sanitizer-thread"));
+        reason!(!has_hwasan && config.parse_name_directive(ln, "needs-sanitizer-hwaddress"));
+        reason!(!has_memtag && config.parse_name_directive(ln, "needs-sanitizer-memtag"));
+        reason!(
+            !has_shadow_call_stack
+                && config.parse_name_directive(ln, "needs-sanitizer-shadow-call-stack")
+        );
+        reason!(!config.can_unwind() && config.parse_name_directive(ln, "needs-unwind"));
+        reason!(
+            config.target == "wasm32-unknown-unknown"
+                && config.parse_name_directive(ln, directives::CHECK_RUN_RESULTS)
+        );
+        reason!(config.debugger == Some(Debugger::Cdb) && ignore_cdb(config, ln));
+        reason!(config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln));
+        reason!(config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln));
+        reason!(!has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld"));
         should_fail |= config.parse_name_directive(ln, "should-fail");
     });
 
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 9c16ef2cbec..395bcc745f8 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -68,52 +68,6 @@ def load_json_from_response(resp):
         print("Refusing to decode " + str(type(content)) + " to str")
     return json.loads(content_str)
 
-def validate_maintainers(repo, github_token):
-    # type: (str, str) -> None
-    '''Ensure all maintainers are assignable on a GitHub repo'''
-    next_link_re = re.compile(r'<([^>]+)>; rel="next"')
-
-    # Load the list of assignable people in the GitHub repo
-    assignable = [] # type: typing.List[str]
-    url = 'https://api.github.com/repos/' \
-        + '%s/collaborators?per_page=100' % repo # type: typing.Optional[str]
-    while url is not None:
-        response = urllib2.urlopen(urllib2.Request(url, headers={
-            'Authorization': 'token ' + github_token,
-            # Properly load nested teams.
-            'Accept': 'application/vnd.github.hellcat-preview+json',
-        }))
-        assignable.extend(user['login'] for user in load_json_from_response(response))
-        # Load the next page if available
-        url = None
-        link_header = response.headers.get('Link')
-        if link_header:
-            matches = next_link_re.match(link_header)
-            if matches is not None:
-                url = matches.group(1)
-
-    errors = False
-    for tool, maintainers in MAINTAINERS.items():
-        for maintainer in maintainers:
-            if maintainer not in assignable:
-                errors = True
-                print(
-                    "error: %s maintainer @%s is not assignable in the %s repo"
-                    % (tool, maintainer, repo),
-                )
-
-    if errors:
-        print()
-        print("  To be assignable, a person needs to be explicitly listed as a")
-        print("  collaborator in the repository settings. The simple way to")
-        print("  fix this is to ask someone with 'admin' privileges on the repo")
-        print("  to add the person or whole team as a collaborator with 'read'")
-        print("  privileges. Those privileges don't grant any extra permissions")
-        print("  so it's safe to apply them.")
-        print()
-        print("The build will fail due to this.")
-        exit(1)
-
 
 def read_current_status(current_commit, path):
     # type: (str, str) -> typing.Mapping[str, typing.Any]
@@ -280,21 +234,6 @@ def update_latest(
 try:
     if __name__ != '__main__':
         exit(0)
-    repo = os.environ.get('TOOLSTATE_VALIDATE_MAINTAINERS_REPO')
-    if repo:
-        github_token = os.environ.get('TOOLSTATE_REPO_ACCESS_TOKEN')
-        if github_token:
-            # FIXME: This is currently broken. Starting on 2021-09-15, GitHub
-            # seems to have changed it so that to list the collaborators
-            # requires admin permissions. I think this will probably just need
-            # to be removed since we are probably not going to use an admin
-            # token, and I don't see another way to do this.
-            print('maintainer validation disabled')
-            # validate_maintainers(repo, github_token)
-        else:
-            print('skipping toolstate maintainers validation since no GitHub token is present')
-        # When validating maintainers don't run the full script.
-        exit(0)
 
     cur_commit = sys.argv[1]
     cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
diff --git a/tests/rustdoc-gui/src-font-size.goml b/tests/rustdoc-gui/src-font-size.goml
index 9233f37444b..bab66dae70c 100644
--- a/tests/rustdoc-gui/src-font-size.goml
+++ b/tests/rustdoc-gui/src-font-size.goml
@@ -4,13 +4,13 @@
 goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 show-text: true
 // Check the impl headers.
-assert-css: (".impl.has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
-assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weight": 600}, ALL)
+assert-css: (".impl .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
+assert-css: (".impl .code-header", {"font-size": "18px", "font-weight": 600}, ALL)
 // Check the impl items.
-assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
-assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
+assert-css: (".impl-items .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
+assert-css: (".impl-items .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
 
 // Check that we can click on source link
 store-document-property: (url, "URL")
-click: ".impl-items .has-srclink .srclink"
+click: ".impl-items .srclink"
 assert-document-property-false: {"URL": |url|}
diff --git a/tests/rustdoc/anchors.no_const_anchor.html b/tests/rustdoc/anchors.no_const_anchor.html
index 75e67330a3e..a8587829d3e 100644
--- a/tests/rustdoc/anchors.no_const_anchor.html
+++ b/tests/rustdoc/anchors.no_const_anchor.html
@@ -1 +1 @@
-<section id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
+<section id="associatedconstant.YOLO" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_const_anchor2.html b/tests/rustdoc/anchors.no_const_anchor2.html
index c0025197602..4c5e45fea2d 100644
--- a/tests/rustdoc/anchors.no_const_anchor2.html
+++ b/tests/rustdoc/anchors.no_const_anchor2.html
@@ -1 +1 @@
-<section id="associatedconstant.X" class="associatedconstant has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#42">source</a><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section>
\ No newline at end of file
+<section id="associatedconstant.X" class="associatedconstant"><a class="srclink rightside" href="../src/foo/anchors.rs.html#42">source</a><h4 class="code-header">pub const <a href="#associatedconstant.X" class="constant">X</a>: <a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a> = 0i32</h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_method_anchor.html b/tests/rustdoc/anchors.no_method_anchor.html
index b9ec8bf4c09..44957a5b71a 100644
--- a/tests/rustdoc/anchors.no_method_anchor.html
+++ b/tests/rustdoc/anchors.no_method_anchor.html
@@ -1 +1 @@
-<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -&gt; Self</h4></section>
\ No newline at end of file
+<section id="method.new" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -&gt; Self</h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_trait_method_anchor.html b/tests/rustdoc/anchors.no_trait_method_anchor.html
index 4308ddad412..75c2caf87a8 100644
--- a/tests/rustdoc/anchors.no_trait_method_anchor.html
+++ b/tests/rustdoc/anchors.no_trait_method_anchor.html
@@ -1 +1 @@
-<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section>
\ No newline at end of file
+<section id="method.bar" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_tymethod_anchor.html b/tests/rustdoc/anchors.no_tymethod_anchor.html
index 91eed8a3742..38575eadfa9 100644
--- a/tests/rustdoc/anchors.no_tymethod_anchor.html
+++ b/tests/rustdoc/anchors.no_tymethod_anchor.html
@@ -1 +1 @@
-<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section>
\ No newline at end of file
+<section id="tymethod.foo" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_type_anchor.html b/tests/rustdoc/anchors.no_type_anchor.html
index 2c66d5aa315..dd65d98fee6 100644
--- a/tests/rustdoc/anchors.no_type_anchor.html
+++ b/tests/rustdoc/anchors.no_type_anchor.html
@@ -1 +1 @@
-<section id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section>
\ No newline at end of file
+<section id="associatedtype.T" class="method"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/anchors.no_type_anchor2.html b/tests/rustdoc/anchors.no_type_anchor2.html
index 72a1186bf7e..f8b59160f15 100644
--- a/tests/rustdoc/anchors.no_type_anchor2.html
+++ b/tests/rustdoc/anchors.no_type_anchor2.html
@@ -1 +1 @@
-<section id="associatedtype.Y" class="associatedtype has-srclink"><h4 class="code-header">type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
+<section id="associatedtype.Y" class="associatedtype"><h4 class="code-header">type <a href="#associatedtype.Y" class="associatedtype">Y</a> = <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section>
\ No newline at end of file
diff --git a/tests/rustdoc/async-fn.rs b/tests/rustdoc/async-fn.rs
index fb7ebb5f822..8cafb5a2497 100644
--- a/tests/rustdoc/async-fn.rs
+++ b/tests/rustdoc/async-fn.rs
@@ -77,12 +77,12 @@ struct AsyncFdReadyGuard<'a, T> { x: &'a T }
 
 impl Foo {
     // @has async_fn/struct.Foo.html
-    // @has - '//*[@class="method has-srclink"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
+    // @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar) -> impl Iterator<Item = &usize>'
     pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {}
     // taken from `tokio` as an example of a method that was particularly bad before
-    // @has - '//*[@class="method has-srclink"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
+    // @has - '//*[@class="method"]' "pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()>"
     pub async fn readable<T>(&self) -> Result<AsyncFdReadyGuard<'_, T>, ()> {}
-    // @has - '//*[@class="method has-srclink"]' "pub async fn mut_self(&mut self)"
+    // @has - '//*[@class="method"]' "pub async fn mut_self(&mut self)"
     pub async fn mut_self(&mut self) {}
 }
 
diff --git a/tests/rustdoc/const-fn.rs b/tests/rustdoc/const-fn.rs
index 4366ad4d0ad..18863abaeac 100644
--- a/tests/rustdoc/const-fn.rs
+++ b/tests/rustdoc/const-fn.rs
@@ -8,7 +8,7 @@ pub const fn bar() -> usize {
 }
 
 // @has foo/struct.Foo.html
-// @has - '//*[@class="method has-srclink"]' 'const fn new()'
+// @has - '//*[@class="method"]' 'const fn new()'
 pub struct Foo(usize);
 
 impl Foo {
diff --git a/tests/rustdoc/const-generics/const-generic-slice.rs b/tests/rustdoc/const-generics/const-generic-slice.rs
index 4279de91f56..80a9ab3f12e 100644
--- a/tests/rustdoc/const-generics/const-generic-slice.rs
+++ b/tests/rustdoc/const-generics/const-generic-slice.rs
@@ -5,7 +5,7 @@ pub trait Array {
 }
 
 // @has foo/trait.Array.html
-// @has - '//*[@class="impl has-srclink"]' 'impl<T, const N: usize> Array for [T; N]'
+// @has - '//*[@class="impl"]' 'impl<T, const N: usize> Array for [T; N]'
 impl<T, const N: usize> Array for [T; N] {
     type Item = T;
 }
diff --git a/tests/rustdoc/doc-assoc-item.rs b/tests/rustdoc/doc-assoc-item.rs
index 4f15418650c..4d5c9f83e1e 100644
--- a/tests/rustdoc/doc-assoc-item.rs
+++ b/tests/rustdoc/doc-assoc-item.rs
@@ -8,7 +8,7 @@ pub trait Bar {
     fn foo(foo: Self::Fuu);
 }
 
-// @has doc_assoc_item/struct.Foo.html '//*[@class="impl has-srclink"]' 'impl<T: Bar<Fuu = u32>> Foo<T>'
+// @has doc_assoc_item/struct.Foo.html '//*[@class="impl"]' 'impl<T: Bar<Fuu = u32>> Foo<T>'
 impl<T: Bar<Fuu = u32>> Foo<T> {
     pub fn new(t: T) -> Foo<T> {
         Foo {
diff --git a/tests/rustdoc/duplicate_impls/issue-33054.rs b/tests/rustdoc/duplicate_impls/issue-33054.rs
index c1f95ac91c3..4c2071b8322 100644
--- a/tests/rustdoc/duplicate_impls/issue-33054.rs
+++ b/tests/rustdoc/duplicate_impls/issue-33054.rs
@@ -3,8 +3,8 @@
 // @has issue_33054/impls/struct.Foo.html
 // @has - '//h3[@class="code-header"]' 'impl Foo'
 // @has - '//h3[@class="code-header"]' 'impl Bar for Foo'
-// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1
-// @count - '//*[@id="main-content"]/div[@id="implementations-list"]/details/summary/*[@class="impl has-srclink"]' 1
+// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+// @count - '//*[@id="main-content"]/div[@id="implementations-list"]/details/summary/*[@class="impl"]' 1
 // @has issue_33054/impls/bar/trait.Bar.html
 // @has - '//h3[@class="code-header"]' 'impl Bar for Foo'
 // @count - '//*[@class="struct"]' 1
diff --git a/tests/rustdoc/duplicated_impl.rs b/tests/rustdoc/duplicated_impl.rs
index 4e901b31c90..f32cf310055 100644
--- a/tests/rustdoc/duplicated_impl.rs
+++ b/tests/rustdoc/duplicated_impl.rs
@@ -7,7 +7,7 @@
 // blanket implementations.
 
 // @has 'foo/struct.Whatever.html'
-// @count - '//*[@id="blanket-implementations-list"]/section[@class="impl has-srclink"]' 1
+// @count - '//*[@id="blanket-implementations-list"]/section[@class="impl"]' 1
 
 pub trait Something<T> { }
 pub struct Whatever;
diff --git a/tests/rustdoc/empty-impl-block-private-with-doc.rs b/tests/rustdoc/empty-impl-block-private-with-doc.rs
index 43971996163..e6cff97b184 100644
--- a/tests/rustdoc/empty-impl-block-private-with-doc.rs
+++ b/tests/rustdoc/empty-impl-block-private-with-doc.rs
@@ -10,7 +10,7 @@ pub struct Foo;
 // There are 3 impl blocks with public item and one that should not be displayed
 // by default because it only contains private items (but not in this case because
 // we used `--document-private-items`).
-// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 4
+// @count - '//*[@class="impl"]' 'impl Foo' 4
 
 // Impl block only containing private items should not be displayed unless the
 // `--document-private-items` flag is used.
diff --git a/tests/rustdoc/empty-impl-block-private.rs b/tests/rustdoc/empty-impl-block-private.rs
index 5caf020658c..d44b4a47cee 100644
--- a/tests/rustdoc/empty-impl-block-private.rs
+++ b/tests/rustdoc/empty-impl-block-private.rs
@@ -7,7 +7,7 @@ pub struct Foo;
 
 // There are 3 impl blocks with public item and one that should not be displayed
 // because it only contains private items.
-// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 3
+// @count - '//*[@class="impl"]' 'impl Foo' 3
 
 // Impl block only containing private items should not be displayed.
 /// Private
diff --git a/tests/rustdoc/empty-impl-block.rs b/tests/rustdoc/empty-impl-block.rs
index 95d4db06b31..da780580bd0 100644
--- a/tests/rustdoc/empty-impl-block.rs
+++ b/tests/rustdoc/empty-impl-block.rs
@@ -8,7 +8,7 @@ pub struct Foo;
 /// Hello empty impl block!
 impl Foo {}
 // We ensure that this empty impl block without doc isn't rendered.
-// @count - '//*[@class="impl has-srclink"]' 'impl Foo' 1
+// @count - '//*[@class="impl"]' 'impl Foo' 1
 impl Foo {}
 
 // Just to ensure that empty trait impl blocks are rendered.
diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl-parts.rs
index 90cbb77cb6b..f7738060e99 100644
--- a/tests/rustdoc/impl-parts.rs
+++ b/tests/rustdoc/impl-parts.rs
@@ -5,7 +5,7 @@ pub auto trait AnAutoTrait {}
 
 pub struct Foo<T> { field: T }
 
-// @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
 // @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
 //     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
diff --git a/tests/rustdoc/inline_cross/issue-31948-1.rs b/tests/rustdoc/inline_cross/issue-31948-1.rs
index 6e89167b3a4..571eaf6be96 100644
--- a/tests/rustdoc/inline_cross/issue-31948-1.rs
+++ b/tests/rustdoc/inline_cross/issue-31948-1.rs
@@ -5,8 +5,8 @@
 extern crate rustdoc_nonreachable_impls;
 
 // @has issue_31948_1/struct.Wobble.html
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for'
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
 // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
 pub use rustdoc_nonreachable_impls::hidden::Wobble;
diff --git a/tests/rustdoc/inline_cross/issue-31948-2.rs b/tests/rustdoc/inline_cross/issue-31948-2.rs
index 141e07656a0..7eae21046cc 100644
--- a/tests/rustdoc/inline_cross/issue-31948-2.rs
+++ b/tests/rustdoc/inline_cross/issue-31948-2.rs
@@ -5,9 +5,9 @@
 extern crate rustdoc_nonreachable_impls;
 
 // @has issue_31948_2/struct.Wobble.html
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Qux for'
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for'
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
 // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 pub use rustdoc_nonreachable_impls::hidden::Wobble;
 
diff --git a/tests/rustdoc/inline_cross/issue-31948.rs b/tests/rustdoc/inline_cross/issue-31948.rs
index 96fc6ca47e7..9c271bf4ad4 100644
--- a/tests/rustdoc/inline_cross/issue-31948.rs
+++ b/tests/rustdoc/inline_cross/issue-31948.rs
@@ -5,9 +5,9 @@
 extern crate rustdoc_nonreachable_impls;
 
 // @has issue_31948/struct.Foo.html
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bark for'
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Woof for'
-// @!has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'Bar for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bark for'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'Woof for'
+// @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Bar for'
 // @!has - '//*[@class="impl"]//h3[@class="code-header"]' 'Qux for'
 pub use rustdoc_nonreachable_impls::Foo;
 
diff --git a/tests/rustdoc/issue-21474.rs b/tests/rustdoc/issue-21474.rs
index 43ce13fd9b1..5de26abace6 100644
--- a/tests/rustdoc/issue-21474.rs
+++ b/tests/rustdoc/issue-21474.rs
@@ -7,5 +7,5 @@ mod inner {
 pub trait Blah { }
 
 // @count issue_21474/struct.What.html \
-//        '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1
+//        '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
 pub struct What;
diff --git a/tests/rustdoc/issue-33302.rs b/tests/rustdoc/issue-33302.rs
index b4c52e2f17a..7af00c77836 100644
--- a/tests/rustdoc/issue-33302.rs
+++ b/tests/rustdoc/issue-33302.rs
@@ -22,7 +22,7 @@ macro_rules! make {
         }
 
         // @has issue_33302/struct.S.html \
-        //        '//*[@class="impl has-srclink"]' 'impl T<[i32; 16]> for S'
+        //        '//*[@class="impl"]' 'impl T<[i32; 16]> for S'
         // @has - '//*[@id="associatedconstant.C"]' 'const C: [i32; 16]'
         // @has - '//*[@id="associatedconstant.D"]' 'const D: i32'
         impl T<[i32; ($n * $n)]> for S {
@@ -30,7 +30,7 @@ macro_rules! make {
         }
 
         // @has issue_33302/struct.S.html \
-        //        '//*[@class="impl has-srclink"]' 'impl T<[i32; 16]> for S'
+        //        '//*[@class="impl"]' 'impl T<[i32; 16]> for S'
         // @has - '//*[@id="associatedconstant.C-1"]' 'const C: (i32,)'
         // @has - '//*[@id="associatedconstant.D-1"]' 'const D: i32'
         impl T<(i32,)> for S {
@@ -38,7 +38,7 @@ macro_rules! make {
         }
 
         // @has issue_33302/struct.S.html \
-        //        '//*[@class="impl has-srclink"]' 'impl T<(i32, i32)> for S'
+        //        '//*[@class="impl"]' 'impl T<(i32, i32)> for S'
         // @has - '//*[@id="associatedconstant.C-2"]' 'const C: (i32, i32)'
         // @has - '//*[@id="associatedconstant.D-2"]' 'const D: i32'
         impl T<(i32, i32)> for S {
diff --git a/tests/rustdoc/issue-45584.rs b/tests/rustdoc/issue-45584.rs
index 86479e6fb2e..8a5f0413826 100644
--- a/tests/rustdoc/issue-45584.rs
+++ b/tests/rustdoc/issue-45584.rs
@@ -4,12 +4,12 @@ pub trait Bar<T, U> {}
 
 // @has 'foo/struct.Foo1.html'
 pub struct Foo1;
-// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1
-// @has - '//*[@class="impl has-srclink"]' "impl Bar<Foo1, &'static Foo1> for Foo1"
+// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+// @has - '//*[@class="impl"]' "impl Bar<Foo1, &'static Foo1> for Foo1"
 impl Bar<Foo1, &'static Foo1> for Foo1 {}
 
 // @has 'foo/struct.Foo2.html'
 pub struct Foo2;
-// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1
-// @has - '//*[@class="impl has-srclink"]' "impl Bar<&'static Foo2, Foo2> for u8"
+// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+// @has - '//*[@class="impl"]' "impl Bar<&'static Foo2, Foo2> for u8"
 impl Bar<&'static Foo2, Foo2> for u8 {}
diff --git a/tests/rustdoc/issue-50159.rs b/tests/rustdoc/issue-50159.rs
index 04bc4f304d6..13bedd5dbb0 100644
--- a/tests/rustdoc/issue-50159.rs
+++ b/tests/rustdoc/issue-50159.rs
@@ -14,7 +14,7 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
 // @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
 // @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
 pub struct Switch<B: Signal> {
     pub inner: <B as Signal2>::Item2,
 }
diff --git a/tests/rustdoc/issue-51236.rs b/tests/rustdoc/issue-51236.rs
index 1c7aa9c7eef..04664805a88 100644
--- a/tests/rustdoc/issue-51236.rs
+++ b/tests/rustdoc/issue-51236.rs
@@ -7,7 +7,7 @@ pub mod traits {
 }
 
 // @has issue_51236/struct.Owned.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> Send for Owned<T>where <T as Owned<'static>>::Reader: Send"
 pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
     marker: PhantomData<<T as ::traits::Owned<'static>>::Reader>,
diff --git a/tests/rustdoc/issue-53812.rs b/tests/rustdoc/issue-53812.rs
index c68ffd52186..dc1eb304c3d 100644
--- a/tests/rustdoc/issue-53812.rs
+++ b/tests/rustdoc/issue-53812.rs
@@ -12,9 +12,9 @@ macro_rules! array_impls {
 }
 
 // @has issue_53812/trait.MyIterator.html
-// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][1]' 'MyStruct<[T; 0]>'
-// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][2]' 'MyStruct<[T; 1]>'
-// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][3]' 'MyStruct<[T; 2]>'
-// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][4]' 'MyStruct<[T; 3]>'
-// @has - '//*[@id="implementors-list"]/*[@class="impl has-srclink"][5]' 'MyStruct<[T; 10]>'
+// @has - '//*[@id="implementors-list"]/*[@class="impl"][1]' 'MyStruct<[T; 0]>'
+// @has - '//*[@id="implementors-list"]/*[@class="impl"][2]' 'MyStruct<[T; 1]>'
+// @has - '//*[@id="implementors-list"]/*[@class="impl"][3]' 'MyStruct<[T; 2]>'
+// @has - '//*[@id="implementors-list"]/*[@class="impl"][4]' 'MyStruct<[T; 3]>'
+// @has - '//*[@id="implementors-list"]/*[@class="impl"][5]' 'MyStruct<[T; 10]>'
 array_impls! { 10 3 2 1 0 }
diff --git a/tests/rustdoc/issue-54705.rs b/tests/rustdoc/issue-54705.rs
index 7b7290ab4b7..a886eb0de24 100644
--- a/tests/rustdoc/issue-54705.rs
+++ b/tests/rustdoc/issue-54705.rs
@@ -1,10 +1,10 @@
 pub trait ScopeHandle<'scope> {}
 
 // @has issue_54705/struct.ScopeFutureContents.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'scope, S> Send for ScopeFutureContents<'scope, S>where S: Sync"
 //
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'scope, S> Sync for ScopeFutureContents<'scope, S>where S: Sync"
 pub struct ScopeFutureContents<'scope, S>
     where S: ScopeHandle<'scope>,
diff --git a/tests/rustdoc/issue-55321.rs b/tests/rustdoc/issue-55321.rs
index 22a18ef90e1..d3c2070d915 100644
--- a/tests/rustdoc/issue-55321.rs
+++ b/tests/rustdoc/issue-55321.rs
@@ -1,9 +1,9 @@
 #![feature(negative_impls)]
 
 // @has issue_55321/struct.A.html
-// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl !Send for A"
-// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl !Sync for A"
 pub struct A();
 
@@ -11,8 +11,8 @@ impl !Send for A {}
 impl !Sync for A {}
 
 // @has issue_55321/struct.B.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Send for B<T>"
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Sync for B<T>"
 pub struct B<T: ?Sized>(A, Box<T>);
diff --git a/tests/rustdoc/issue-56822.rs b/tests/rustdoc/issue-56822.rs
index b4eef344b5f..c9a74335702 100644
--- a/tests/rustdoc/issue-56822.rs
+++ b/tests/rustdoc/issue-56822.rs
@@ -17,7 +17,7 @@ impl<'a, T> MyTrait for Inner<'a, T> {
 }
 
 // @has issue_56822/struct.Parser.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'a> Send for Parser<'a>"
 pub struct Parser<'a> {
     field: <Wrapper<Inner<'a, u8>> as MyTrait>::Output
diff --git a/tests/rustdoc/issue-60726.rs b/tests/rustdoc/issue-60726.rs
index fbb0f82ae39..e337e4a4f7a 100644
--- a/tests/rustdoc/issue-60726.rs
+++ b/tests/rustdoc/issue-60726.rs
@@ -26,9 +26,9 @@ where
 {}
 
 // @has issue_60726/struct.IntoIter.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Send for IntoIter<T>"
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Sync for IntoIter<T>"
 pub struct IntoIter<T>{
     hello:DynTrait<FooInterface<T>>,
diff --git a/tests/rustdoc/issue-76501.rs b/tests/rustdoc/issue-76501.rs
index a90e0fea092..5caea0ec992 100644
--- a/tests/rustdoc/issue-76501.rs
+++ b/tests/rustdoc/issue-76501.rs
@@ -8,7 +8,7 @@ pub const fn bloop() -> i32 {
 pub struct Struct {}
 
 impl Struct {
-    // @has 'issue_76501/struct.Struct.html' '//*[@class="method has-srclink"]' \
+    // @has 'issue_76501/struct.Struct.html' '//*[@class="method"]' \
     // 'pub const fn blurp() -> i32'
     /// A useless function that always returns 1.
     pub const fn blurp() -> i32 {
diff --git a/tests/rustdoc/issue-78673.rs b/tests/rustdoc/issue-78673.rs
index 2e4bec2544c..d09141c3204 100644
--- a/tests/rustdoc/issue-78673.rs
+++ b/tests/rustdoc/issue-78673.rs
@@ -7,8 +7,8 @@ pub trait AnAmazingTrait {}
 impl<T: Something> AnAmazingTrait for T {}
 
 // @has 'issue_78673/struct.MyStruct.html'
-// @has  - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for MyStruct'
-// @!has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for T'
+// @has  - '//*[@class="impl"]' 'AnAmazingTrait for MyStruct'
+// @!has - '//*[@class="impl"]' 'AnAmazingTrait for T'
 pub struct MyStruct;
 
 impl AnAmazingTrait for MyStruct {}
@@ -16,8 +16,8 @@ impl AnAmazingTrait for MyStruct {}
 // generic structs may have _both_ specific and blanket impls that apply
 
 // @has 'issue_78673/struct.AnotherStruct.html'
-// @has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for AnotherStruct<()>'
-// @has - '//*[@class="impl has-srclink"]' 'AnAmazingTrait for T'
+// @has - '//*[@class="impl"]' 'AnAmazingTrait for AnotherStruct<()>'
+// @has - '//*[@class="impl"]' 'AnAmazingTrait for T'
 pub struct AnotherStruct<T>(T);
 
 impl<T: Something> Something for AnotherStruct<T> {}
diff --git a/tests/rustdoc/mut-params.rs b/tests/rustdoc/mut-params.rs
index 3b862e651c9..431db51d95f 100644
--- a/tests/rustdoc/mut-params.rs
+++ b/tests/rustdoc/mut-params.rs
@@ -5,7 +5,7 @@
 
 pub struct Foo;
 
-// @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method has-srclink"]' 2
+// @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2
 // @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut'
 impl Foo {
     pub fn foo(mut self) {}
diff --git a/tests/rustdoc/negative-impl.rs b/tests/rustdoc/negative-impl.rs
index af19c784d6d..51223af6737 100644
--- a/tests/rustdoc/negative-impl.rs
+++ b/tests/rustdoc/negative-impl.rs
@@ -5,10 +5,10 @@ pub struct Alpha;
 // @matches negative_impl/struct.Bravo.html '//pre' "pub struct Bravo<B>"
 pub struct Bravo<B>(B);
 
-// @matches negative_impl/struct.Alpha.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @matches negative_impl/struct.Alpha.html '//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl !Send for Alpha"
 impl !Send for Alpha {}
 
-// @matches negative_impl/struct.Bravo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' "\
+// @matches negative_impl/struct.Bravo.html '//*[@class="impl"]//h3[@class="code-header"]' "\
 // impl<B> !Send for Bravo<B>"
 impl<B> !Send for Bravo<B> {}
diff --git a/tests/rustdoc/primitive-reference.rs b/tests/rustdoc/primitive-reference.rs
index c3a5eb6d324..10efbefd2b1 100644
--- a/tests/rustdoc/primitive-reference.rs
+++ b/tests/rustdoc/primitive-reference.rs
@@ -13,7 +13,7 @@
 // @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
 
 // There should be only one implementation listed.
-// @count - '//*[@class="impl has-srclink"]' 1
+// @count - '//*[@class="impl"]' 1
 // @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \
 //        'impl<A, B> Foo<&A> for &B'
 #[doc(primitive = "reference")]
diff --git a/tests/rustdoc/pub-method.rs b/tests/rustdoc/pub-method.rs
index 0dca3f672cd..7115a01d079 100644
--- a/tests/rustdoc/pub-method.rs
+++ b/tests/rustdoc/pub-method.rs
@@ -10,8 +10,8 @@ pub fn bar() -> usize {
 }
 
 // @has foo/struct.Foo.html
-// @has - '//*[@class="method has-srclink"]' 'pub fn new()'
-// @has - '//*[@class="method has-srclink"]' 'fn not_pub()'
+// @has - '//*[@class="method"]' 'pub fn new()'
+// @has - '//*[@class="method"]' 'fn not_pub()'
 pub struct Foo(usize);
 
 impl Foo {
diff --git a/tests/rustdoc/synthetic_auto/basic.rs b/tests/rustdoc/synthetic_auto/basic.rs
index 7c6a388653c..043ac241488 100644
--- a/tests/rustdoc/synthetic_auto/basic.rs
+++ b/tests/rustdoc/synthetic_auto/basic.rs
@@ -1,8 +1,8 @@
 // @has basic/struct.Foo.html
 // @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send'
 // @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync'
-// @count - '//*[@id="implementations-list"]//*[@class="impl has-srclink"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 5
+// @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
 pub struct Foo<T> {
     field: T,
 }
diff --git a/tests/rustdoc/synthetic_auto/complex.rs b/tests/rustdoc/synthetic_auto/complex.rs
index 43393c21fdd..4c39f0bf1e0 100644
--- a/tests/rustdoc/synthetic_auto/complex.rs
+++ b/tests/rustdoc/synthetic_auto/complex.rs
@@ -20,7 +20,7 @@ mod foo {
 }
 
 // @has complex/struct.NotOuter.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'a, T, K: ?Sized> Send for Outer<'a, T, K>where K: for<'b> Fn((&'b bool, &'a u8)) \
 // -> &'b i8, T: MyTrait<'a>, <T as MyTrait<'a>>::MyItem: Copy, 'a: 'static"
 
diff --git a/tests/rustdoc/synthetic_auto/lifetimes.rs b/tests/rustdoc/synthetic_auto/lifetimes.rs
index 33170a84435..71265b3078a 100644
--- a/tests/rustdoc/synthetic_auto/lifetimes.rs
+++ b/tests/rustdoc/synthetic_auto/lifetimes.rs
@@ -9,10 +9,10 @@ where
 {}
 
 // @has lifetimes/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'c, K> Send for Foo<'c, K>where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static"
 //
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'c, K> Sync for Foo<'c, K>where K: Sync"
 pub struct Foo<'c, K: 'c> {
     inner_field: Inner<'c, K>,
diff --git a/tests/rustdoc/synthetic_auto/manual.rs b/tests/rustdoc/synthetic_auto/manual.rs
index 77c04ad2ad9..7fc8447df3e 100644
--- a/tests/rustdoc/synthetic_auto/manual.rs
+++ b/tests/rustdoc/synthetic_auto/manual.rs
@@ -1,12 +1,12 @@
 // @has manual/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // 'impl<T> Sync for Foo<T>where T: Sync'
 //
-// @has - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="trait-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // 'impl<T> Send for Foo<T>'
 //
-// @count - '//*[@id="trait-implementations-list"]//*[@class="impl has-srclink"]' 1
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]' 4
+// @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
 pub struct Foo<T> {
     field: T,
 }
diff --git a/tests/rustdoc/synthetic_auto/negative.rs b/tests/rustdoc/synthetic_auto/negative.rs
index 2c2c848a5e0..97da2d57424 100644
--- a/tests/rustdoc/synthetic_auto/negative.rs
+++ b/tests/rustdoc/synthetic_auto/negative.rs
@@ -3,10 +3,10 @@ pub struct Inner<T: Copy> {
 }
 
 // @has negative/struct.Outer.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Send for Outer<T>"
 //
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> !Sync for Outer<T>"
 pub struct Outer<T: Copy> {
     inner_field: Inner<T>,
diff --git a/tests/rustdoc/synthetic_auto/nested.rs b/tests/rustdoc/synthetic_auto/nested.rs
index 423bf115ab1..e4aead71bf2 100644
--- a/tests/rustdoc/synthetic_auto/nested.rs
+++ b/tests/rustdoc/synthetic_auto/nested.rs
@@ -9,10 +9,10 @@ where
 }
 
 // @has nested/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // 'impl<T> Send for Foo<T>where T: Copy'
 //
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // 'impl<T> Sync for Foo<T>where T: Sync'
 pub struct Foo<T> {
     inner_field: Inner<T>,
diff --git a/tests/rustdoc/synthetic_auto/no-redundancy.rs b/tests/rustdoc/synthetic_auto/no-redundancy.rs
index 59f33623322..ea57d7388b8 100644
--- a/tests/rustdoc/synthetic_auto/no-redundancy.rs
+++ b/tests/rustdoc/synthetic_auto/no-redundancy.rs
@@ -9,7 +9,7 @@ where
 }
 
 // @has no_redundancy/struct.Outer.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> Send for Outer<T>where T: Send + Copy"
 pub struct Outer<T> {
     inner_field: Inner<T>,
diff --git a/tests/rustdoc/synthetic_auto/project.rs b/tests/rustdoc/synthetic_auto/project.rs
index 558ff2add40..7c9412ae962 100644
--- a/tests/rustdoc/synthetic_auto/project.rs
+++ b/tests/rustdoc/synthetic_auto/project.rs
@@ -23,10 +23,10 @@ where
 }
 
 // @has project/struct.Foo.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'c, K> Send for Foo<'c, K>where K: MyTrait<MyItem = bool>, 'c: 'static"
 //
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<'c, K> Sync for Foo<'c, K>where K: MyTrait, <K as MyTrait>::MyItem: OtherTrait, \
 // 'c: 'static,"
 pub struct Foo<'c, K: 'c> {
diff --git a/tests/rustdoc/synthetic_auto/self-referential.rs b/tests/rustdoc/synthetic_auto/self-referential.rs
index c6ae96de776..145a2b7e00c 100644
--- a/tests/rustdoc/synthetic_auto/self-referential.rs
+++ b/tests/rustdoc/synthetic_auto/self-referential.rs
@@ -23,7 +23,7 @@ impl<T> Pattern for Wrapper<T> {
 
 
 // @has self_referential/struct.WriteAndThen.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<P1> Send for WriteAndThen<P1>where    <P1 as Pattern>::Value: Send"
 pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value)
     where P1: Pattern;
diff --git a/tests/rustdoc/synthetic_auto/static-region.rs b/tests/rustdoc/synthetic_auto/static-region.rs
index 1a76cb919c2..9dc6211ec20 100644
--- a/tests/rustdoc/synthetic_auto/static-region.rs
+++ b/tests/rustdoc/synthetic_auto/static-region.rs
@@ -3,7 +3,7 @@ pub trait OwnedTrait<'a> {
 }
 
 // @has static_region/struct.Owned.html
-// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
 // "impl<T> Send for Owned<T>where <T as OwnedTrait<'static>>::Reader: Send"
 pub struct Owned<T> where T: OwnedTrait<'static> {
     marker: <T as OwnedTrait<'static>>::Reader,
diff --git a/tests/rustdoc/typedef.rs b/tests/rustdoc/typedef.rs
index d5dfa948489..63e2973c759 100644
--- a/tests/rustdoc/typedef.rs
+++ b/tests/rustdoc/typedef.rs
@@ -9,8 +9,8 @@ impl MyStruct {
 }
 
 // @has typedef/type.MyAlias.html
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'impl MyAlias'
-// @has - '//*[@class="impl has-srclink"]//h3[@class="code-header"]' 'impl MyTrait for MyAlias'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'impl MyAlias'
+// @has - '//*[@class="impl"]//h3[@class="code-header"]' 'impl MyTrait for MyAlias'
 // @hasraw - 'Alias docstring'
 // @has - '//*[@class="sidebar"]//*[@class="location"]' 'MyAlias'
 // @has - '//*[@class="sidebar"]//a[@href="#implementations"]' 'Methods'
diff --git a/tests/rustdoc/where.rs b/tests/rustdoc/where.rs
index 3ac0c6872a8..644a0058244 100644
--- a/tests/rustdoc/where.rs
+++ b/tests/rustdoc/where.rs
@@ -13,7 +13,7 @@ pub fn charlie<C>() where C: MyTrait {}
 
 pub struct Delta<D>(D);
 
-// @has foo/struct.Delta.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has foo/struct.Delta.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //          "impl<D> Delta<D>where D: MyTrait"
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
@@ -43,7 +43,7 @@ pub trait TraitWhere {
     { todo!() }
 }
 
-// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has foo/struct.Echo.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //          "impl<E> MyTrait for Echo<E>where E: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
 //          "impl<E> MyTrait for Echo<E>where E: MyTrait"
@@ -51,7 +51,7 @@ impl<E> MyTrait for Echo<E>where E: MyTrait {}
 
 pub enum Foxtrot<F> { Foxtrot1(F) }
 
-// @has foo/enum.Foxtrot.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
+// @has foo/enum.Foxtrot.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //          "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
 //          "impl<F> MyTrait for Foxtrot<F>where F: MyTrait"
diff --git a/tests/ui/parser/trait-object-delimiters.rs b/tests/ui/parser/trait-object-delimiters.rs
index cc04ac05204..c41cda18743 100644
--- a/tests/ui/parser/trait-object-delimiters.rs
+++ b/tests/ui/parser/trait-object-delimiters.rs
@@ -5,6 +5,8 @@ fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
 
 fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
 
+fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
+
 fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
 //~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
 //~| ERROR at least one trait is required for an object type
diff --git a/tests/ui/parser/trait-object-delimiters.stderr b/tests/ui/parser/trait-object-delimiters.stderr
index 99c4515459d..ccce3a8053e 100644
--- a/tests/ui/parser/trait-object-delimiters.stderr
+++ b/tests/ui/parser/trait-object-delimiters.stderr
@@ -13,17 +13,29 @@ LL | fn foo2(_: &dyn (Drop + AsRef<str>)) {}
 help: remove the parentheses
    |
 LL - fn foo2(_: &dyn (Drop + AsRef<str>)) {}
-LL + fn foo2(_: &dyn Drop + AsRef<str>) {}
+LL + fn foo2(_: &dyn  Drop + AsRef<str>) {}
+   |
+
+error: incorrect braces around trait bounds
+  --> $DIR/trait-object-delimiters.rs:8:25
+   |
+LL | fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
+   |                         ^                 ^
+   |
+help: remove the parentheses
+   |
+LL - fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
+LL + fn foo2_no_space(_: &dyn Drop + AsRef<str>) {}
    |
 
 error: expected parameter name, found `{`
-  --> $DIR/trait-object-delimiters.rs:8:17
+  --> $DIR/trait-object-delimiters.rs:10:17
    |
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |                 ^ expected parameter name
 
 error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
-  --> $DIR/trait-object-delimiters.rs:8:17
+  --> $DIR/trait-object-delimiters.rs:10:17
    |
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |                -^ expected one of 10 possible tokens
@@ -31,13 +43,13 @@ LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |                help: missing `,`
 
 error: expected identifier, found `<`
-  --> $DIR/trait-object-delimiters.rs:12:17
+  --> $DIR/trait-object-delimiters.rs:14:17
    |
 LL | fn foo4(_: &dyn <Drop + AsRef<str>>) {}
    |                 ^ expected identifier
 
 error: invalid `dyn` keyword
-  --> $DIR/trait-object-delimiters.rs:14:25
+  --> $DIR/trait-object-delimiters.rs:16:25
    |
 LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
    |                         ^^^ help: remove this keyword
@@ -56,13 +68,13 @@ LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
 error[E0224]: at least one trait is required for an object type
-  --> $DIR/trait-object-delimiters.rs:8:13
+  --> $DIR/trait-object-delimiters.rs:10:13
    |
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |             ^^^
 
 error[E0225]: only auto traits can be used as additional traits in a trait object
-  --> $DIR/trait-object-delimiters.rs:14:29
+  --> $DIR/trait-object-delimiters.rs:16:29
    |
 LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
    |                  ----       ^^^^^^^^^^ additional non-auto trait
@@ -72,7 +84,7 @@ LL | fn foo5(_: &(dyn Drop + dyn AsRef<str>)) {}
    = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Drop + AsRef<str> {}`
    = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0224, E0225.
 For more information about an error, try `rustc --explain E0224`.
diff --git a/tests/ui/thir-print/thir-flat.rs b/tests/ui/thir-print/thir-flat.rs
new file mode 100644
index 00000000000..8fa95ce62b5
--- /dev/null
+++ b/tests/ui/thir-print/thir-flat.rs
@@ -0,0 +1,4 @@
+// compile-flags: -Z unpretty=thir-flat
+// check-pass
+
+pub fn main() {}
diff --git a/tests/ui/thir-tree.stdout b/tests/ui/thir-print/thir-flat.stdout
index 4b6915f7715..c399fa66b6a 100644
--- a/tests/ui/thir-tree.stdout
+++ b/tests/ui/thir-print/thir-flat.stdout
@@ -1,4 +1,4 @@
-DefId(0:3 ~ thir_tree[8f1d]::main):
+DefId(0:3 ~ thir_flat[45a6]::main):
 Thir {
     arms: [],
     blocks: [
@@ -6,7 +6,7 @@ Thir {
             targeted_by_break: false,
             region_scope: Node(1),
             opt_destruction_scope: None,
-            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
             stmts: [],
             expr: None,
             safety_mode: Safe,
@@ -18,7 +18,7 @@ Thir {
             temp_lifetime: Some(
                 Node(2),
             ),
-            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
             kind: Block {
                 block: b0,
             },
@@ -28,11 +28,11 @@ Thir {
             temp_lifetime: Some(
                 Node(2),
             ),
-            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
             kind: Scope {
                 region_scope: Node(2),
                 lint_level: Explicit(
-                    HirId(DefId(0:3 ~ thir_tree[8f1d]::main).2),
+                    HirId(DefId(0:3 ~ thir_flat[45a6]::main).2),
                 ),
                 value: e0,
             },
@@ -42,7 +42,7 @@ Thir {
             temp_lifetime: Some(
                 Node(2),
             ),
-            span: $DIR/thir-tree.rs:4:15: 4:17 (#0),
+            span: $DIR/thir-flat.rs:4:15: 4:17 (#0),
             kind: Scope {
                 region_scope: Destruction(2),
                 lint_level: Inherited,
diff --git a/tests/ui/thir-print/thir-tree-match.rs b/tests/ui/thir-print/thir-tree-match.rs
new file mode 100644
index 00000000000..a5511ec9543
--- /dev/null
+++ b/tests/ui/thir-print/thir-tree-match.rs
@@ -0,0 +1,23 @@
+// check-pass
+// compile-flags: -Zunpretty=thir-tree
+
+enum Bar {
+    First,
+    Second,
+    Third,
+}
+
+enum Foo {
+    FooOne(Bar),
+    FooTwo,
+}
+
+fn has_match(foo: Foo) -> bool {
+    match foo {
+        Foo::FooOne(Bar::First) => true,
+        Foo::FooOne(_) => false,
+        Foo::FooTwo => true,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout
new file mode 100644
index 00000000000..d6174ec262a
--- /dev/null
+++ b/tests/ui/thir-print/thir-tree-match.stdout
@@ -0,0 +1,342 @@
+DefId(0:16 ~ thir_tree_match[3c9a]::has_match):
+params: [
+    Param {
+        ty: Foo
+        ty_span: Some($DIR/thir-tree-match.rs:15:19: 15:22 (#0))
+        self_kind: None
+        hir_id: Some(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).1))
+        param: Some( 
+            Pat: {
+                ty: Foo
+                span: $DIR/thir-tree-match.rs:15:14: 15:17 (#0)
+                kind: PatKind {
+                    Binding {
+                        mutability: Not
+                        name: "foo"
+                        mode: ByValue
+                        var: LocalVarId(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).2))
+                        ty: Foo
+                        is_primary: true
+                        subpattern: None
+                    }
+                }
+            }
+        )
+    }
+]
+body:
+    Expr {
+        ty: bool
+        temp_lifetime: Some(Node(26))
+        span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
+        kind: 
+            Scope {
+                region_scope: Destruction(26)
+                lint_level: Inherited
+                value:
+                    Expr {
+                        ty: bool
+                        temp_lifetime: Some(Node(26))
+                        span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
+                        kind: 
+                            Scope {
+                                region_scope: Node(26)
+                                lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).26))
+                                value:
+                                    Expr {
+                                        ty: bool
+                                        temp_lifetime: Some(Node(26))
+                                        span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
+                                        kind: 
+                                            Block {
+                                                targeted_by_break: false
+                                                opt_destruction_scope: None
+                                                span: $DIR/thir-tree-match.rs:15:32: 21:2 (#0)
+                                                region_scope: Node(25)
+                                                safety_mode: Safe
+                                                stmts: []
+                                                expr:
+                                                    Expr {
+                                                        ty: bool
+                                                        temp_lifetime: Some(Node(26))
+                                                        span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
+                                                        kind: 
+                                                            Scope {
+                                                                region_scope: Node(3)
+                                                                lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).3))
+                                                                value:
+                                                                    Expr {
+                                                                        ty: bool
+                                                                        temp_lifetime: Some(Node(26))
+                                                                        span: $DIR/thir-tree-match.rs:16:5: 20:6 (#0)
+                                                                        kind: 
+                                                                            Match {
+                                                                                scrutinee:
+                                                                                    Expr {
+                                                                                        ty: Foo
+                                                                                        temp_lifetime: Some(Node(26))
+                                                                                        span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
+                                                                                        kind: 
+                                                                                            Scope {
+                                                                                                region_scope: Node(4)
+                                                                                                lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).4))
+                                                                                                value:
+                                                                                                    Expr {
+                                                                                                        ty: Foo
+                                                                                                        temp_lifetime: Some(Node(26))
+                                                                                                        span: $DIR/thir-tree-match.rs:16:11: 16:14 (#0)
+                                                                                                        kind: 
+                                                                                                            VarRef {
+                                                                                                                id: LocalVarId(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).2))
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                    }
+                                                                                arms: [
+                                                                                    Arm {
+                                                                                        pattern: 
+                                                                                            Pat: {
+                                                                                                ty: Foo
+                                                                                                span: $DIR/thir-tree-match.rs:17:9: 17:32 (#0)
+                                                                                                kind: PatKind {
+                                                                                                    Variant {
+                                                                                                        adt_def: 
+                                                                                                            AdtDef {
+                                                                                                                did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
+                                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
+                                                                                                                flags: IS_ENUM
+                                                                                                                repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
+                                                                                                        substs: []
+                                                                                                        variant_index: 0
+                                                                                                        subpatterns: [
+                                                                                                            Pat: {
+                                                                                                                ty: Bar
+                                                                                                                span: $DIR/thir-tree-match.rs:17:21: 17:31 (#0)
+                                                                                                                kind: PatKind {
+                                                                                                                    Variant {
+                                                                                                                        adt_def: 
+                                                                                                                            AdtDef {
+                                                                                                                                did: DefId(0:3 ~ thir_tree_match[3c9a]::Bar)
+                                                                                                                                variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[3c9a]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[3c9a]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[3c9a]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[3c9a]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[3c9a]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[3c9a]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], flags: NO_VARIANT_FLAGS }]
+                                                                                                                                flags: IS_ENUM
+                                                                                                                                repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 3125160937860410723 }
+                                                                                                                        substs: []
+                                                                                                                        variant_index: 0
+                                                                                                                        subpatterns: []
+                                                                                                                    }
+                                                                                                                }
+                                                                                                            }
+                                                                                                        ]
+                                                                                                    }
+                                                                                                }
+                                                                                            }
+                                                                                        guard: None
+                                                                                        body: 
+                                                                                            Expr {
+                                                                                                ty: bool
+                                                                                                temp_lifetime: Some(Node(13))
+                                                                                                span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
+                                                                                                kind: 
+                                                                                                    Scope {
+                                                                                                        region_scope: Destruction(13)
+                                                                                                        lint_level: Inherited
+                                                                                                        value:
+                                                                                                            Expr {
+                                                                                                                ty: bool
+                                                                                                                temp_lifetime: Some(Node(13))
+                                                                                                                span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
+                                                                                                                kind: 
+                                                                                                                    Scope {
+                                                                                                                        region_scope: Node(13)
+                                                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).13))
+                                                                                                                        value:
+                                                                                                                            Expr {
+                                                                                                                                ty: bool
+                                                                                                                                temp_lifetime: Some(Node(13))
+                                                                                                                                span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0)
+                                                                                                                                kind: 
+                                                                                                                                    Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:17:36: 17:40 (#0) }, neg: false)
+
+                                                                                                                            }
+                                                                                                                    }
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).12))
+                                                                                        scope: Node(12)
+                                                                                        span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0)
+                                                                                    }
+                                                                                    Arm {
+                                                                                        pattern: 
+                                                                                            Pat: {
+                                                                                                ty: Foo
+                                                                                                span: $DIR/thir-tree-match.rs:18:9: 18:23 (#0)
+                                                                                                kind: PatKind {
+                                                                                                    Variant {
+                                                                                                        adt_def: 
+                                                                                                            AdtDef {
+                                                                                                                did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
+                                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
+                                                                                                                flags: IS_ENUM
+                                                                                                                repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
+                                                                                                        substs: []
+                                                                                                        variant_index: 0
+                                                                                                        subpatterns: [
+                                                                                                            Pat: {
+                                                                                                                ty: Bar
+                                                                                                                span: $DIR/thir-tree-match.rs:18:21: 18:22 (#0)
+                                                                                                                kind: PatKind {
+                                                                                                                    Wild
+                                                                                                                }
+                                                                                                            }
+                                                                                                        ]
+                                                                                                    }
+                                                                                                }
+                                                                                            }
+                                                                                        guard: None
+                                                                                        body: 
+                                                                                            Expr {
+                                                                                                ty: bool
+                                                                                                temp_lifetime: Some(Node(19))
+                                                                                                span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
+                                                                                                kind: 
+                                                                                                    Scope {
+                                                                                                        region_scope: Destruction(19)
+                                                                                                        lint_level: Inherited
+                                                                                                        value:
+                                                                                                            Expr {
+                                                                                                                ty: bool
+                                                                                                                temp_lifetime: Some(Node(19))
+                                                                                                                span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
+                                                                                                                kind: 
+                                                                                                                    Scope {
+                                                                                                                        region_scope: Node(19)
+                                                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).19))
+                                                                                                                        value:
+                                                                                                                            Expr {
+                                                                                                                                ty: bool
+                                                                                                                                temp_lifetime: Some(Node(19))
+                                                                                                                                span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0)
+                                                                                                                                kind: 
+                                                                                                                                    Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-match.rs:18:27: 18:32 (#0) }, neg: false)
+
+                                                                                                                            }
+                                                                                                                    }
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).18))
+                                                                                        scope: Node(18)
+                                                                                        span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0)
+                                                                                    }
+                                                                                    Arm {
+                                                                                        pattern: 
+                                                                                            Pat: {
+                                                                                                ty: Foo
+                                                                                                span: $DIR/thir-tree-match.rs:19:9: 19:20 (#0)
+                                                                                                kind: PatKind {
+                                                                                                    Variant {
+                                                                                                        adt_def: 
+                                                                                                            AdtDef {
+                                                                                                                did: DefId(0:10 ~ thir_tree_match[3c9a]::Foo)
+                                                                                                                variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[3c9a]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[3c9a]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[3c9a]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[3c9a])) }], flags: NO_VARIANT_FLAGS }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[3c9a]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[3c9a]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: NO_VARIANT_FLAGS }]
+                                                                                                                flags: IS_ENUM
+                                                                                                                repr: ReprOptions { int: None, align: None, pack: None, flags: (empty), field_shuffle_seed: 11573694388057581 }
+                                                                                                        substs: []
+                                                                                                        variant_index: 1
+                                                                                                        subpatterns: []
+                                                                                                    }
+                                                                                                }
+                                                                                            }
+                                                                                        guard: None
+                                                                                        body: 
+                                                                                            Expr {
+                                                                                                ty: bool
+                                                                                                temp_lifetime: Some(Node(24))
+                                                                                                span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
+                                                                                                kind: 
+                                                                                                    Scope {
+                                                                                                        region_scope: Destruction(24)
+                                                                                                        lint_level: Inherited
+                                                                                                        value:
+                                                                                                            Expr {
+                                                                                                                ty: bool
+                                                                                                                temp_lifetime: Some(Node(24))
+                                                                                                                span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
+                                                                                                                kind: 
+                                                                                                                    Scope {
+                                                                                                                        region_scope: Node(24)
+                                                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).24))
+                                                                                                                        value:
+                                                                                                                            Expr {
+                                                                                                                                ty: bool
+                                                                                                                                temp_lifetime: Some(Node(24))
+                                                                                                                                span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0)
+                                                                                                                                kind: 
+                                                                                                                                    Literal( lit: Spanned { node: Bool(true), span: $DIR/thir-tree-match.rs:19:24: 19:28 (#0) }, neg: false)
+
+                                                                                                                            }
+                                                                                                                    }
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                        lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[3c9a]::has_match).23))
+                                                                                        scope: Node(23)
+                                                                                        span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0)
+                                                                                    }
+                                                                                ]
+                                                                            }
+                                                                    }
+                                                            }
+                                                    }
+                                            }
+                                    }
+                            }
+                    }
+            }
+    }
+
+
+DefId(0:17 ~ thir_tree_match[3c9a]::main):
+params: [
+]
+body:
+    Expr {
+        ty: ()
+        temp_lifetime: Some(Node(2))
+        span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
+        kind: 
+            Scope {
+                region_scope: Destruction(2)
+                lint_level: Inherited
+                value:
+                    Expr {
+                        ty: ()
+                        temp_lifetime: Some(Node(2))
+                        span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
+                        kind: 
+                            Scope {
+                                region_scope: Node(2)
+                                lint_level: Explicit(HirId(DefId(0:17 ~ thir_tree_match[3c9a]::main).2))
+                                value:
+                                    Expr {
+                                        ty: ()
+                                        temp_lifetime: Some(Node(2))
+                                        span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
+                                        kind: 
+                                            Block {
+                                                targeted_by_break: false
+                                                opt_destruction_scope: None
+                                                span: $DIR/thir-tree-match.rs:23:11: 23:13 (#0)
+                                                region_scope: Node(1)
+                                                safety_mode: Safe
+                                                stmts: []
+                                                expr: []
+                                            }
+                                    }
+                            }
+                    }
+            }
+    }
+
+
diff --git a/tests/ui/thir-tree.rs b/tests/ui/thir-print/thir-tree.rs
index 32df7905adb..32df7905adb 100644
--- a/tests/ui/thir-tree.rs
+++ b/tests/ui/thir-print/thir-tree.rs
diff --git a/tests/ui/thir-print/thir-tree.stdout b/tests/ui/thir-print/thir-tree.stdout
new file mode 100644
index 00000000000..0a35d9fb78c
--- /dev/null
+++ b/tests/ui/thir-print/thir-tree.stdout
@@ -0,0 +1,43 @@
+DefId(0:3 ~ thir_tree[8f1d]::main):
+params: [
+]
+body:
+    Expr {
+        ty: ()
+        temp_lifetime: Some(Node(2))
+        span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
+        kind: 
+            Scope {
+                region_scope: Destruction(2)
+                lint_level: Inherited
+                value:
+                    Expr {
+                        ty: ()
+                        temp_lifetime: Some(Node(2))
+                        span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
+                        kind: 
+                            Scope {
+                                region_scope: Node(2)
+                                lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree[8f1d]::main).2))
+                                value:
+                                    Expr {
+                                        ty: ()
+                                        temp_lifetime: Some(Node(2))
+                                        span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
+                                        kind: 
+                                            Block {
+                                                targeted_by_break: false
+                                                opt_destruction_scope: None
+                                                span: $DIR/thir-tree.rs:4:15: 4:17 (#0)
+                                                region_scope: Node(1)
+                                                safety_mode: Safe
+                                                stmts: []
+                                                expr: []
+                                            }
+                                    }
+                            }
+                    }
+            }
+    }
+
+