Rollup merge of #108456 - clubby789:ast-passes-diag-migrate, r=compiler-errors

Complete migrating `ast_passes` to derive diagnostics

cc #100717

```@rustbot``` label +A-translation
diff --git a/Cargo.lock b/Cargo.lock
index 3ffa9e5..a226a10 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1927,8 +1927,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
 dependencies = [
- "compiler_builtins",
  "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
+dependencies = [
+ "compiler_builtins",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
 ]
@@ -5294,7 +5302,7 @@
  "dlmalloc",
  "fortanix-sgx-abi",
  "hashbrown 0.12.3",
- "hermit-abi 0.2.6",
+ "hermit-abi 0.3.0",
  "libc",
  "miniz_oxide",
  "object 0.29.0",
@@ -5489,10 +5497,8 @@
 name = "test"
 version = "0.0.0"
 dependencies = [
- "cfg-if",
  "core",
  "getopts",
- "libc",
  "panic_abort",
  "panic_unwind",
  "proc_macro",
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 262e093..7a1066f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1494,7 +1494,7 @@
         assert!(root_place.projection.is_empty());
         let proper_span = self.body.local_decls[root_place.local].source_info.span;
 
-        let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection);
+        let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection);
 
         if self.access_place_error_reported.contains(&(
             Place { local: root_place.local, projection: root_place_projection },
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index c4e7e1f..a49da3d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2633,7 +2633,7 @@
             DefKind::InlineConst => substs.as_inline_const().parent_substs(),
             other => bug!("unexpected item {:?}", other),
         };
-        let parent_substs = tcx.intern_substs(parent_substs);
+        let parent_substs = tcx.mk_substs(parent_substs);
 
         assert_eq!(typeck_root_substs.len(), parent_substs.len());
         if let Err(_) = self.eq_substs(
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 3e87317..e058fe0 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -516,7 +516,7 @@
                 let va_list_ty =
                     self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
 
-                unnormalized_input_tys = self.infcx.tcx.mk_type_list(
+                unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
                     unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
                 );
             }
@@ -656,7 +656,7 @@
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let closure_sig = substs.as_closure().sig();
                 let inputs_and_output = closure_sig.inputs_and_output();
-                let bound_vars = tcx.mk_bound_variable_kinds(
+                let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                     inputs_and_output
                         .bound_vars()
                         .iter()
@@ -680,7 +680,7 @@
                 };
 
                 ty::Binder::bind_with_vars(
-                    tcx.mk_type_list(
+                    tcx.mk_type_list_from_iter(
                         iter::once(closure_ty).chain(inputs).chain(iter::once(output)),
                     ),
                     bound_vars,
@@ -693,7 +693,7 @@
                 let output = substs.as_generator().return_ty();
                 let generator_ty = tcx.mk_generator(def_id, substs, movability);
                 let inputs_and_output =
-                    self.infcx.tcx.intern_type_list(&[generator_ty, resume_ty, output]);
+                    self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]);
                 ty::Binder::dummy(inputs_and_output)
             }
 
@@ -709,13 +709,13 @@
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity();
                 let ty = indices.fold_to_region_vids(tcx, ty);
-                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
+                ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
 
             DefiningTy::InlineConst(def_id, substs) => {
                 assert_eq!(self.mir_def.did.to_def_id(), def_id);
                 let ty = substs.as_inline_const().ty();
-                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
+                ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 3c34585..74396a6 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -405,9 +405,9 @@
     };
 
     let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
-    let extra_args = fx
-        .tcx
-        .mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
+    let extra_args = fx.tcx.mk_type_list_from_iter(
+        extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))),
+    );
     let fn_abi = if let Some(instance) = instance {
         RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
     } else {
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
index b4a2537..40bfe70 100644
--- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
+++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
@@ -56,7 +56,7 @@
                     Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
                 }
             } else {
-                let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
+                let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
                 let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
                 let lhs = lhs.load_scalar(fx);
                 let rhs = rhs.load_scalar(fx);
@@ -78,7 +78,7 @@
         }
         BinOp::Add | BinOp::Sub | BinOp::Mul => {
             assert!(checked);
-            let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
+            let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]);
             let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
             let (param_types, args) = if fx.tcx.sess.target.is_like_windows {
                 let (lhs_ptr, lhs_extra) = lhs.force_stack(fx);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index cbac2e6..e5c4b24 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -191,7 +191,7 @@
     // carry0 | carry1 -> carry or borrow respectively
     let cb_out = fx.bcx.ins().bor(cb0, cb1);
 
-    let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64]));
+    let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, fx.tcx.types.u64]));
     let val = CValue::by_val_pair(cb_out, c, layout);
     ret.write_cvalue(fx, val);
 }
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index 2632710..be908df 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -119,7 +119,7 @@
                     tcx,
                     ParamEnv::reveal_all(),
                     report.def_id,
-                    tcx.intern_substs(&[GenericArg::from(main_ret_ty)]),
+                    tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
                 )
                 .unwrap()
                 .unwrap()
@@ -146,7 +146,7 @@
                     tcx,
                     ParamEnv::reveal_all(),
                     start_def_id,
-                    tcx.intern_substs(&[main_ret_ty.into()]),
+                    tcx.mk_substs(&[main_ret_ty.into()]),
                 )
                 .unwrap()
                 .unwrap()
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index 05905a7..c058ece 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -289,7 +289,7 @@
         _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
     };
 
-    let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool]));
+    let out_layout = fx.layout_of(fx.tcx.mk_tup(&[in_lhs.layout().ty, fx.tcx.types.bool]));
     CValue::by_val_pair(res, has_overflow, out_layout)
 }
 
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 4424b31..4570063 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -383,7 +383,7 @@
                     tcx,
                     ty::ParamEnv::reveal_all(),
                     def_id,
-                    tcx.intern_substs(&[]),
+                    ty::List::empty(),
                 )
                 .unwrap().unwrap(),
             ),
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 37ee0e1..3d29968 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -520,14 +520,9 @@
         let tcx = self.tcx;
         let llfn = match tcx.lang_items().eh_personality() {
             Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr(
-                ty::Instance::resolve(
-                    tcx,
-                    ty::ParamEnv::reveal_all(),
-                    def_id,
-                    tcx.intern_substs(&[]),
-                )
-                .unwrap()
-                .unwrap(),
+                ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty())
+                    .unwrap()
+                    .unwrap(),
             ),
             _ => {
                 let name = if wants_msvc_seh(self.sess()) {
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 11bd47a..067a3e1 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -373,7 +373,7 @@
                 ExportedSymbol::Generic(def_id, substs) => (def_id, substs),
                 ExportedSymbol::DropGlue(ty) => {
                     if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id {
-                        (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()]))
+                        (drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()]))
                     } else {
                         // `drop_in_place` in place does not exist, don't try
                         // to use it.
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 4e13d4d..7317924 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -476,7 +476,7 @@
                     cx.tcx(),
                     ty::ParamEnv::reveal_all(),
                     start_def_id,
-                    cx.tcx().intern_substs(&[main_ret_ty.into()]),
+                    cx.tcx().mk_substs(&[main_ret_ty.into()]),
                 )
                 .unwrap()
                 .unwrap(),
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index cdc3e1d..f6c1b7a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -783,7 +783,7 @@
         };
 
         let extra_args = &args[sig.inputs().skip_binder().len()..];
-        let extra_args = bx.tcx().mk_type_list(extra_args.iter().map(|op_arg| {
+        let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| {
             let op_ty = op_arg.ty(self.mir, bx.tcx());
             self.monomorphize(op_ty)
         }));
@@ -1547,7 +1547,7 @@
             slot
         } else {
             let layout = cx.layout_of(
-                cx.tcx().intern_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]),
+                cx.tcx().mk_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]),
             );
             let slot = PlaceRef::alloca(bx, layout);
             self.personality_slot = Some(slot);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 41cd1c0..3d85698 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -413,7 +413,7 @@
                     lhs.layout.ty,
                 );
                 let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
-                let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]);
+                let operand_ty = bx.tcx().mk_tup(&[val_ty, bx.tcx().types.bool]);
                 OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
             }
 
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 45f7c75..7564ba1 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -180,7 +180,7 @@
                         (ecx.tcx.global_alloc(alloc_id).unwrap_memory(), offset.bytes())
                     }
                     (None, _offset) => (
-                        ecx.tcx.intern_const_alloc(Allocation::from_bytes_byte_aligned_immutable(
+                        ecx.tcx.mk_const_alloc(Allocation::from_bytes_byte_aligned_immutable(
                             b"" as &[u8],
                         )),
                         0,
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 21ef183..b220d21 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -135,7 +135,7 @@
     };
     // link the alloc id to the actual allocation
     leftover_allocations.extend(alloc.provenance().ptrs().iter().map(|&(_, alloc_id)| alloc_id));
-    let alloc = tcx.intern_const_alloc(alloc);
+    let alloc = tcx.mk_const_alloc(alloc);
     tcx.set_alloc_id_memory(alloc_id, alloc);
     None
 }
@@ -437,7 +437,7 @@
                     alloc.mutability = Mutability::Not;
                 }
             }
-            let alloc = tcx.intern_const_alloc(alloc);
+            let alloc = tcx.mk_const_alloc(alloc);
             tcx.set_alloc_id_memory(alloc_id, alloc);
             for &(_, alloc_id) in alloc.inner().provenance().ptrs().iter() {
                 if leftover_allocations.insert(alloc_id) {
@@ -479,6 +479,6 @@
         f(self, &dest.into())?;
         let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1;
         alloc.mutability = Mutability::Not;
-        Ok(self.tcx.intern_const_alloc(alloc))
+        Ok(self.tcx.mk_const_alloc(alloc))
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index c5d558a..6e47646 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -45,7 +45,7 @@
 pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
     let path = crate::util::type_name(tcx, ty);
     let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
-    tcx.intern_const_alloc(alloc)
+    tcx.mk_const_alloc(alloc)
 }
 
 /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
index f6a3937..cf52299 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -96,7 +96,7 @@
         let loc_ty = self
             .tcx
             .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
-            .subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()]));
+            .subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()]));
         let loc_layout = self.layout_of(loc_ty).unwrap();
         let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
 
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 4221200..4decfe8 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -19,7 +19,7 @@
     ) -> InterpResult<'tcx> {
         let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?;
         debug_assert_eq!(
-            self.tcx.intern_tup(&[ty, self.tcx.types.bool]),
+            self.tcx.mk_tup(&[ty, self.tcx.types.bool]),
             dest.layout.ty,
             "type mismatch for result of {:?}",
             op,
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index d934cfb..2aea7c7 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -73,7 +73,8 @@
                 let fn_sig =
                     self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder);
                 let extra_args = &args[fn_sig.inputs().len()..];
-                let extra_args = self.tcx.mk_type_list(extra_args.iter().map(|arg| arg.layout.ty));
+                let extra_args =
+                    self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout.ty));
 
                 let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() {
                     ty::FnPtr(_sig) => {
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index ba08f5d3..3f3b66b 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -866,7 +866,7 @@
 
             let mut projection = vec![PlaceElem::Deref];
             projection.extend(place.projection);
-            place.projection = tcx.intern_place_elems(&projection);
+            place.projection = tcx.mk_place_elems(&projection);
 
             // Create a temp to hold the promoted reference.
             // This is because `*r` requires `r` to be a local,
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3af2d0c..0684916 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -315,7 +315,7 @@
                 }
             }
             ProjectionElem::Field(f, ty) => {
-                let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+                let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
                 let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
                 let fail_out_of_bounds = |this: &Self, location| {
                     this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 800f3c5..9720121 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -253,6 +253,7 @@
 E0468: include_str!("./error_codes/E0468.md"),
 E0469: include_str!("./error_codes/E0469.md"),
 E0472: include_str!("./error_codes/E0472.md"),
+E0476: include_str!("./error_codes/E0476.md"),
 E0477: include_str!("./error_codes/E0477.md"),
 E0478: include_str!("./error_codes/E0478.md"),
 E0482: include_str!("./error_codes/E0482.md"),
@@ -611,7 +612,6 @@
 //  E0473, // dereference of reference outside its lifetime
 //  E0474, // captured variable `..` does not outlive the enclosing closure
 //  E0475, // index of slice outside its lifetime
-    E0476, // lifetime of the source pointer does not outlive lifetime bound...
 //  E0479, // the type `..` (provided as the value of a type parameter) is...
 //  E0480, // lifetime of method receiver does not outlive the method call
 //  E0481, // lifetime of function argument does not outlive the function call
diff --git a/compiler/rustc_error_codes/src/error_codes/E0476.md b/compiler/rustc_error_codes/src/error_codes/E0476.md
new file mode 100644
index 0000000..fc141ba
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0476.md
@@ -0,0 +1,21 @@
+The coerced type does not outlive the value being coerced to.
+
+Example of erroneous code:
+
+```compile_fail,E0476
+#![feature(coerce_unsized)]
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+// error: lifetime of the source pointer does not outlive lifetime bound of the
+//        object type
+impl<'a, 'b, T, S> CoerceUnsized<&'a T> for &'b S where S: Unsize<T> {}
+```
+
+During a coercion, the "source pointer" (the coerced type) did not outlive the
+"object type" (value being coerced to). In the above example, `'b` is not a
+subtype of `'a`. This error can currently only be encountered with the unstable
+`CoerceUnsized` trait which allows custom coercions of unsized types behind a
+smart pointer to be implemented.
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 40ed10e..010e5f0 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -135,7 +135,10 @@
 
     let fallback_locale = langid!("en-US");
     let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale);
-
+    trace!(?requested_fallback_locale);
+    if requested_fallback_locale && additional_ftl_path.is_none() {
+        return Ok(None);
+    }
     // If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user
     // provided locale.
     let locale = requested_locale.clone().unwrap_or(fallback_locale);
@@ -153,7 +156,7 @@
     bundle.set_use_isolating(with_directionality_markers);
 
     // If the user requests the default locale then don't try to load anything.
-    if !requested_fallback_locale && let Some(requested_locale) = requested_locale {
+    if let Some(requested_locale) = requested_locale {
         let mut found_resources = false;
         for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
             sysroot.push("share");
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index 1ac9b8e..ed35eb1 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -1,4 +1,4 @@
-use crate::error::TranslateError;
+use crate::error::{TranslateError, TranslateErrorKind};
 use crate::snippet::Style;
 use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle};
 use rustc_data_structures::sync::Lrc;
@@ -95,6 +95,16 @@
                 // The primary bundle was present and translation succeeded
                 Some(Ok(t)) => t,
 
+                // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely
+                // just that the primary bundle doesn't contain the message being translated, so
+                // proceed to the fallback bundle.
+                Some(Err(
+                    primary @ TranslateError::One {
+                        kind: TranslateErrorKind::MessageMissing, ..
+                    },
+                )) => translate_with_bundle(self.fallback_fluent_bundle())
+                    .map_err(|fallback| primary.and(fallback))?,
+
                 // Always yeet out for errors on debug (unless
                 // `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows
                 // local runs of the test suites, of builds with debug assertions, to test the
@@ -106,9 +116,8 @@
                     do yeet primary
                 }
 
-                // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely
-                // just that the primary bundle doesn't contain the message being translated or
-                // something else went wrong) so proceed to the fallback bundle.
+                // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
+                // just hide it and try with the fallback bundle.
                 Some(Err(primary)) => translate_with_bundle(self.fallback_fluent_bundle())
                     .map_err(|fallback| primary.and(fallback))?,
 
diff --git a/compiler/rustc_expand/locales/en-US.ftl b/compiler/rustc_expand/locales/en-US.ftl
index dbd8095..b475d28 100644
--- a/compiler/rustc_expand/locales/en-US.ftl
+++ b/compiler/rustc_expand/locales/en-US.ftl
@@ -129,3 +129,7 @@
     .help = delete or rename one of them to remove the ambiguity
 
 expand_trace_macro = trace_macro
+
+expand_proc_macro_panicked =
+    proc macro panicked
+    .help = message: {$message}
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index d9b2b5f..70ab222 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -375,3 +375,18 @@
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(expand_proc_macro_panicked)]
+pub(crate) struct ProcMacroPanicked {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub message: Option<ProcMacroPanickedHelp>,
+}
+
+#[derive(Subdiagnostic)]
+#[help(expand_help)]
+pub(crate) struct ProcMacroPanickedHelp {
+    pub message: String,
+}
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index e9a6919..cef64a1 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -1,4 +1,5 @@
 use crate::base::{self, *};
+use crate::errors;
 use crate::proc_macro_server;
 
 use rustc_ast as ast;
@@ -60,11 +61,12 @@
         let strategy = exec_strategy(ecx);
         let server = proc_macro_server::Rustc::new(ecx);
         self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| {
-            let mut err = ecx.struct_span_err(span, "proc macro panicked");
-            if let Some(s) = e.as_str() {
-                err.help(&format!("message: {}", s));
-            }
-            err.emit()
+            ecx.sess.emit_err(errors::ProcMacroPanicked {
+                span,
+                message: e
+                    .as_str()
+                    .map(|message| errors::ProcMacroPanickedHelp { message: message.into() }),
+            })
         })
     }
 }
diff --git a/compiler/rustc_hir_analysis/locales/en-US.ftl b/compiler/rustc_hir_analysis/locales/en-US.ftl
index 7e3a31f..e877311 100644
--- a/compiler/rustc_hir_analysis/locales/en-US.ftl
+++ b/compiler/rustc_hir_analysis/locales/en-US.ftl
@@ -132,3 +132,26 @@
 
 hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
     .label = `main` function is not allowed to be `#[track_caller]`
+
+hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]`
+    .label = `start` is not allowed to be `#[track_caller]`
+
+hir_analysis_start_not_async = `start` is not allowed to be `async`
+    .label = `start` is not allowed to be `async`
+
+hir_analysis_start_function_where = start function is not allowed to have a `where` clause
+    .label = start function cannot have a `where` clause
+
+hir_analysis_start_function_parameters = start function is not allowed to have type parameters
+    .label = start function cannot have type parameters
+
+hir_analysis_main_function_return_type_generic = `main` function return type is not allowed to have generic parameters
+
+hir_analysis_main_function_async = `main` function is not allowed to be `async`
+    .label = `main` function is not allowed to be `async`
+
+hir_analysis_main_function_generic_parameters = `main` function is not allowed to have generic parameters
+    .label = `main` cannot have generic parameters
+
+hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
+    .label = C-variadic function must have a compatible calling convention
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index 499b51e..c49e4d9 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -377,7 +377,7 @@
                     // `<Foo as Iterator>::Item = String`.
                     let projection_ty = pred.skip_binder().projection_ty;
 
-                    let substs_with_infer_self = tcx.mk_substs(
+                    let substs_with_infer_self = tcx.mk_substs_from_iter(
                         std::iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
                             .chain(projection_ty.substs.iter().skip(1)),
                     );
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 630becc..7f6518f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -370,7 +370,7 @@
         }
     }
 
-    tcx.intern_substs(&substs)
+    tcx.mk_substs(&substs)
 }
 
 /// Checks that the correct number of generic arguments have been provided.
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 92dc02c..43dd5b3 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -381,7 +381,7 @@
         // here and so associated type bindings will be handled regardless of whether there are any
         // non-`Self` generic parameters.
         if generics.params.is_empty() {
-            return (tcx.intern_substs(parent_substs), arg_count);
+            return (tcx.mk_substs(parent_substs), arg_count);
         }
 
         struct SubstsForAstPathCtxt<'a, 'tcx> {
@@ -1529,7 +1529,7 @@
                         arg
                     })
                     .collect();
-                let substs = tcx.intern_substs(&substs[..]);
+                let substs = tcx.mk_substs(&substs);
 
                 let span = i.bottom().1;
                 let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
@@ -1591,7 +1591,7 @@
                             arg
                         })
                         .collect();
-                    b.projection_ty.substs = tcx.intern_substs(&substs[..]);
+                    b.projection_ty.substs = tcx.mk_substs(&substs);
                 }
 
                 ty::ExistentialProjection::erase_self_ty(tcx, b)
@@ -1613,7 +1613,7 @@
             .collect::<SmallVec<[_; 8]>>();
         v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
         v.dedup();
-        let existential_predicates = tcx.intern_poly_existential_predicates(&v);
+        let existential_predicates = tcx.mk_poly_existential_predicates(&v);
 
         // Use explicitly-specified region bound.
         let region_bound = if !lifetime.is_elided() {
@@ -2810,7 +2810,7 @@
                             var: ty::BoundVar::from_u32(index),
                             kind: ty::BoundTyKind::Param(def_id, name),
                         };
-                        tcx.mk_ty(ty::Bound(debruijn, br))
+                        tcx.mk_bound(debruijn, br)
                     }
                     Some(rbv::ResolvedArg::EarlyBound(_)) => {
                         let def_id = def_id.expect_local();
@@ -3020,7 +3020,9 @@
                 tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
             }
             hir::TyKind::Never => tcx.types.never,
-            hir::TyKind::Tup(fields) => tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(t))),
+            hir::TyKind::Tup(fields) => {
+                tcx.mk_tup_from_iter(fields.iter().map(|t| self.ast_ty_to_ty(t)))
+            }
             hir::TyKind::BareFn(bf) => {
                 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
 
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index bdc9ff5..89b4e62 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -196,7 +196,7 @@
     // the new hybrid bounds we computed.
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
     let param_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&hybrid_preds.predicates),
+        tcx.mk_predicates(&hybrid_preds.predicates),
         Reveal::UserFacing,
         hir::Constness::NotConst,
     );
@@ -1795,7 +1795,7 @@
     let impl_ty_span = tcx.def_span(impl_ty_def_id);
     let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
     let param_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&hybrid_preds.predicates),
+        tcx.mk_predicates(&hybrid_preds.predicates),
         Reveal::UserFacing,
         hir::Constness::NotConst,
     );
@@ -1937,8 +1937,8 @@
             .into()
         }
     });
-    let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars);
-    let impl_ty_substs = tcx.intern_substs(&substs);
+    let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
+    let impl_ty_substs = tcx.mk_substs(&substs);
     let container_id = impl_ty.container_id(tcx);
 
     let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
@@ -1978,11 +1978,7 @@
                 .to_predicate(tcx),
             ),
         };
-        ty::ParamEnv::new(
-            tcx.intern_predicates(&predicates),
-            Reveal::UserFacing,
-            param_env.constness(),
-        )
+        ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness())
     };
     debug!(?normalize_param_env);
 
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 4720fea..054284c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -137,7 +137,7 @@
     let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
-    let bound_vars = tcx.intern_bound_variable_kinds(&[
+    let bound_vars = tcx.mk_bound_variable_kinds(&[
         ty::BoundVariableKind::Region(ty::BrAnon(0, None)),
         ty::BoundVariableKind::Region(ty::BrEnv),
     ]);
@@ -165,7 +165,7 @@
             "cxchg" | "cxchgweak" => (
                 1,
                 vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)],
-                tcx.intern_tup(&[param(0), tcx.types.bool]),
+                tcx.mk_tup(&[param(0), tcx.types.bool]),
             ),
             "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)),
             "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
@@ -317,7 +317,7 @@
             | sym::bitreverse => (1, vec![param(0)], param(0)),
 
             sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
-                (1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool]))
+                (1, vec![param(0), param(0)], tcx.mk_tup(&[param(0), tcx.types.bool]))
             }
 
             sym::ptr_guaranteed_cmp => {
@@ -372,7 +372,7 @@
                 (
                     1,
                     vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))],
-                    tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])),
+                    tcx.mk_projection(discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
                 )
             }
 
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 25be625..4cccdf3 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -493,8 +493,9 @@
         return param_env;
     }
 
-    let bounds =
-        tcx.mk_predicates(param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()));
+    let bounds = tcx.mk_predicates_from_iter(
+        param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
+    );
     // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
     // i.e. traits::normalize_param_env_or_error
     ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness())
@@ -1476,7 +1477,7 @@
         |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
 
     sig.inputs_and_output =
-        tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
+        tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
             wfcx.normalize(
                 arg_span(idx),
                 Some(WellFormedLoc::Param {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index a290003..604d54c 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -905,7 +905,7 @@
         }
         _ => bug!(),
     };
-    tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr)
+    tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
 }
 
 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 8d479f1..9cf3ff6 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -103,7 +103,7 @@
     tcx: TyCtxt<'_>,
     def_id: DefId,
 ) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> {
-    let bounds = tcx.mk_predicates(
+    let bounds = tcx.mk_predicates_from_iter(
         util::elaborate_predicates(
             tcx,
             tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound),
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index d0fb7af..309d020 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -333,3 +333,70 @@
     #[label]
     pub annotated: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_not_track_caller)]
+pub(crate) struct StartTrackCaller {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub start: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_not_async, code = "E0752")]
+pub(crate) struct StartAsync {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_function_where, code = "E0647")]
+pub(crate) struct StartFunctionWhere {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_start_function_parameters, code = "E0132")]
+pub(crate) struct StartFunctionParameters {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")]
+pub(crate) struct MainFunctionReturnTypeGeneric {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_async, code = "E0752")]
+pub(crate) struct MainFunctionAsync {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub asyncness: Option<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")]
+pub(crate) struct MainFunctionGenericParameters {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub label_span: Option<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")]
+pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub conventions: &'a str,
+}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 9a43ca6..33c132f 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -98,7 +98,7 @@
 pub mod structured_errors;
 mod variance;
 
-use rustc_errors::{struct_span_err, ErrorGuaranteed};
+use rustc_errors::ErrorGuaranteed;
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_hir as hir;
 use rustc_hir::Node;
@@ -123,7 +123,6 @@
 fluent_messages! { "../locales/en-US.ftl" }
 
 fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
-    const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention";
     const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";
     const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
     const UNSTABLE_EXPLAIN: &str =
@@ -155,8 +154,7 @@
         (true, false) => CONVENTIONS_UNSTABLE,
     };
 
-    let mut err = struct_span_err!(tcx.sess, span, E0045, "{}, like {}", ERROR_HEAD, conventions);
-    err.span_label(span, ERROR_HEAD).emit();
+    tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
 }
 
 fn require_same_types<'tcx>(
@@ -258,15 +256,10 @@
     let main_fn_predicates = tcx.predicates_of(main_def_id);
     if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() {
         let generics_param_span = main_fn_generics_params_span(tcx, main_def_id);
-        let msg = "`main` function is not allowed to have generic \
-            parameters";
-        let mut diag =
-            struct_span_err!(tcx.sess, generics_param_span.unwrap_or(main_span), E0131, "{}", msg);
-        if let Some(generics_param_span) = generics_param_span {
-            let label = "`main` cannot have generic parameters";
-            diag.span_label(generics_param_span, label);
-        }
-        diag.emit();
+        tcx.sess.emit_err(errors::MainFunctionGenericParameters {
+            span: generics_param_span.unwrap_or(main_span),
+            label_span: generics_param_span,
+        });
         error = true;
     } else if !main_fn_predicates.predicates.is_empty() {
         // generics may bring in implicit predicates, so we skip this check if generics is present.
@@ -280,17 +273,8 @@
 
     let main_asyncness = tcx.asyncness(main_def_id);
     if let hir::IsAsync::Async = main_asyncness {
-        let mut diag = struct_span_err!(
-            tcx.sess,
-            main_span,
-            E0752,
-            "`main` function is not allowed to be `async`"
-        );
         let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
-        if let Some(asyncness_span) = asyncness_span {
-            diag.span_label(asyncness_span, "`main` function is not allowed to be `async`");
-        }
-        diag.emit();
+        tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
         error = true;
     }
 
@@ -308,9 +292,7 @@
         let return_ty = main_fnsig.output();
         let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
         if !return_ty.bound_vars().is_empty() {
-            let msg = "`main` function return type is not allowed to have generic \
-                    parameters";
-            struct_span_err!(tcx.sess, return_ty_span, E0131, "{}", msg).emit();
+            tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span });
             error = true;
         }
         let return_ty = return_ty.skip_binder();
@@ -367,56 +349,28 @@
                 if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
                     let mut error = false;
                     if !generics.params.is_empty() {
-                        struct_span_err!(
-                            tcx.sess,
-                            generics.span,
-                            E0132,
-                            "start function is not allowed to have type parameters"
-                        )
-                        .span_label(generics.span, "start function cannot have type parameters")
-                        .emit();
+                        tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span });
                         error = true;
                     }
                     if generics.has_where_clause_predicates {
-                        struct_span_err!(
-                            tcx.sess,
-                            generics.where_clause_span,
-                            E0647,
-                            "start function is not allowed to have a `where` clause"
-                        )
-                        .span_label(
-                            generics.where_clause_span,
-                            "start function cannot have a `where` clause",
-                        )
-                        .emit();
+                        tcx.sess.emit_err(errors::StartFunctionWhere {
+                            span: generics.where_clause_span,
+                        });
                         error = true;
                     }
                     if let hir::IsAsync::Async = sig.header.asyncness {
                         let span = tcx.def_span(it.owner_id);
-                        struct_span_err!(
-                            tcx.sess,
-                            span,
-                            E0752,
-                            "`start` is not allowed to be `async`"
-                        )
-                        .span_label(span, "`start` is not allowed to be `async`")
-                        .emit();
+                        tcx.sess.emit_err(errors::StartAsync { span: span });
                         error = true;
                     }
 
                     let attrs = tcx.hir().attrs(start_id);
                     for attr in attrs {
                         if attr.has_name(sym::track_caller) {
-                            tcx.sess
-                                .struct_span_err(
-                                    attr.span,
-                                    "`start` is not allowed to be `#[track_caller]`",
-                                )
-                                .span_label(
-                                    start_span,
-                                    "`start` is not allowed to be `#[track_caller]`",
-                                )
-                                .emit();
+                            tcx.sess.emit_err(errors::StartTrackCaller {
+                                span: attr.span,
+                                start: start_span,
+                            });
                             error = true;
                         }
                     }
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 2cb0d43..cae884a 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -462,7 +462,7 @@
 
         if self.gen_args.span_ext().is_some() {
             format!(
-                "this {} takes {}{} {} argument{} but {} {} supplied",
+                "{} takes {}{} {} argument{} but {} {} supplied",
                 def_kind,
                 quantifier,
                 bound,
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index fe2f631..6a0d5c0 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -232,7 +232,7 @@
             let Some(trait_def_id) = opt_trait_def_id else { continue };
 
             let opt_input_type = opt_arg_exprs.map(|arg_exprs| {
-                self.tcx.mk_tup(arg_exprs.iter().map(|e| {
+                self.tcx.mk_tup_from_iter(arg_exprs.iter().map(|e| {
                     self.next_ty_var(TypeVariableOrigin {
                         kind: TypeVariableOriginKind::TypeInference,
                         span: e.span,
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 6c70042..d84fabb 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -127,7 +127,7 @@
         // the `closures` table.
         let sig = bound_sig.map_bound(|sig| {
             self.tcx.mk_fn_sig(
-                [self.tcx.intern_tup(sig.inputs())],
+                [self.tcx.mk_tup(sig.inputs())],
                 sig.output(),
                 sig.c_variadic,
                 sig.unsafety,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 6d54f69..d192d16 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1492,7 +1492,7 @@
             }
             _ => self.check_expr_with_expectation(&e, NoExpectation),
         });
-        let tuple = self.tcx.mk_tup(elt_ts_iter);
+        let tuple = self.tcx.mk_tup_from_iter(elt_ts_iter);
         if let Err(guar) = tuple.error_reported() {
             self.tcx.ty_error(guar)
         } else {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 9933915..2e62e13 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -102,7 +102,7 @@
 
             let err_inputs = match tuple_arguments {
                 DontTupleArguments => err_inputs,
-                TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
+                TupleArguments => vec![self.tcx.mk_tup(&err_inputs)],
             };
 
             self.check_argument_types(
@@ -642,7 +642,7 @@
                 && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len()
             {
                 // Wrap up the N provided arguments starting at this position in a tuple.
-                let provided_as_tuple = tcx.mk_tup(
+                let provided_as_tuple = tcx.mk_tup_from_iter(
                     provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()),
                 );
 
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
index e5f9292..2e41c20 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
@@ -311,8 +311,8 @@
     };
 
     // Extract type components to build the witness type.
-    let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
-    let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars);
+    let type_list = fcx.tcx.mk_type_list_from_iter(type_causes.iter().map(|cause| cause.ty));
+    let bound_vars = fcx.tcx.mk_bound_variable_kinds(&bound_vars);
     let witness =
         fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone()));
 
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 57c6c15..91fd8fa 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -71,7 +71,7 @@
 use rustc_session::config;
 use rustc_session::Session;
 use rustc_span::def_id::{DefId, LocalDefId};
-use rustc_span::Span;
+use rustc_span::{sym, Span};
 
 fluent_messages! { "../locales/en-US.ftl" }
 
@@ -207,6 +207,11 @@
 
     let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
         let param_env = tcx.param_env(def_id);
+        let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
+            param_env.without_const()
+        } else {
+            param_env
+        };
         let mut fcx = FnCtxt::new(&inh, param_env, def_id);
 
         if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index de8b244..47a4d4e 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -574,7 +574,7 @@
                         // `<Foo as Iterator>::Item = String`.
                         let projection_ty = pred.skip_binder().projection_ty;
 
-                        let substs_with_infer_self = tcx.mk_substs(
+                        let substs_with_infer_self = tcx.mk_substs_from_iter(
                             iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into())
                                 .chain(projection_ty.substs.iter().skip(1)),
                         );
@@ -1252,7 +1252,7 @@
             if let ty::Adt(def, substs) = target_ty.kind() {
                 // If there are any inferred arguments, (`{integer}`), we should replace
                 // them with underscores to allow the compiler to infer them
-                let infer_substs = self.tcx.mk_substs(substs.into_iter().map(|arg| {
+                let infer_substs = self.tcx.mk_substs_from_iter(substs.into_iter().map(|arg| {
                     if !arg.is_suggestable(self.tcx, true) {
                         has_unsuggestable_args = true;
                         match arg.unpack() {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 9d95866..c36c75e 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1302,8 +1302,8 @@
                 TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span },
             )
         });
-        let element_tys = tcx.mk_type_list(element_tys_iter);
-        let pat_ty = tcx.intern_tup(element_tys);
+        let element_tys = tcx.mk_type_list_from_iter(element_tys_iter);
+        let pat_ty = tcx.mk_tup(element_tys);
         if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
             let reported = err.emit();
             // Walk subpatterns with an expected type of `err` in this case to silence
@@ -1312,7 +1312,7 @@
             for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
                 self.check_pat(elem, tcx.ty_error(reported), def_bm, ti);
             }
-            tcx.mk_tup(element_tys_iter)
+            tcx.mk_tup_from_iter(element_tys_iter)
         } else {
             for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
                 self.check_pat(elem, element_tys[i], def_bm, ti);
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 7c8abb4..e94915c 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -301,7 +301,7 @@
 
         // Build a tuple (U0..Un) of the final upvar types U0..Un
         // and unify the upvar tuple type in the closure with it:
-        let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys);
+        let final_tupled_upvars_type = self.tcx.mk_tup(&final_upvar_tys);
         self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type);
 
         let fake_reads = delegate
@@ -315,8 +315,8 @@
             self.typeck_results.borrow_mut().closure_size_eval.insert(
                 closure_def_id,
                 ClosureSizeProfileData {
-                    before_feature_tys: self.tcx.intern_tup(&before_feature_tys),
-                    after_feature_tys: self.tcx.intern_tup(&after_feature_tys),
+                    before_feature_tys: self.tcx.mk_tup(&before_feature_tys),
+                    after_feature_tys: self.tcx.mk_tup(&after_feature_tys),
                 },
             );
         }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index f66f6bd..7ffd39d 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -572,7 +572,7 @@
         debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders());
 
         let canonical_variables =
-            tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
+            tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables());
 
         let max_universe = canonical_variables
             .iter()
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 4053546..8c782a9 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -88,7 +88,7 @@
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> CanonicalVarValues<'tcx> {
         CanonicalVarValues {
-            var_values: self.tcx.mk_substs(
+            var_values: self.tcx.mk_substs_from_iter(
                 variables
                     .iter()
                     .map(|info| self.instantiate_canonical_var(span, info, &universe_map)),
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 07e7589..832af91 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -474,8 +474,8 @@
         // given variable in the loop above, use that. Otherwise, use
         // a fresh inference variable.
         let result_subst = CanonicalVarValues {
-            var_values: self.tcx.mk_substs(query_response.variables.iter().enumerate().map(
-                |(index, info)| {
+            var_values: self.tcx.mk_substs_from_iter(
+                query_response.variables.iter().enumerate().map(|(index, info)| {
                     if info.is_existential() {
                         match opt_values[BoundVar::new(index)] {
                             Some(k) => k,
@@ -488,8 +488,8 @@
                             universe_map[u.as_usize()]
                         })
                     }
-                },
-            )),
+                }),
+            ),
         };
 
         let mut obligations = vec![];
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 9563540..79efc1c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -925,7 +925,7 @@
     ) -> Option<()> {
         // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods,
         // ideally that shouldn't be necessary.
-        let sub = self.tcx.intern_substs(sub);
+        let sub = self.tcx.mk_substs(sub);
         for (i, ta) in sub.types().enumerate() {
             if ta == other_ty {
                 self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
diff --git a/compiler/rustc_lint/locales/en-US.ftl b/compiler/rustc_lint/locales/en-US.ftl
index b1e7cc6..68e62c9 100644
--- a/compiler/rustc_lint/locales/en-US.ftl
+++ b/compiler/rustc_lint/locales/en-US.ftl
@@ -24,6 +24,13 @@
     .use_while_let = to check pattern in a loop use `while let`
     .use_question_mark = consider unwrapping the `Result` with `?` to iterate over its contents
 
+lint_map_unit_fn = `Iterator::map` call that discard the iterator's values
+    .note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+    .function_label = this function returns `()`, which is likely not what you wanted
+    .argument_label = called `Iterator::map` with callable that returns `()`
+    .map_label = after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+    .suggestion = you might have meant to use `Iterator::for_each`
+
 lint_non_binding_let_on_sync_lock =
     non-binding let on a synchronization lock
 
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 4da7f3f..59540aa 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -677,21 +677,21 @@
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             hir::ItemKind::Union(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             hir::ItemKind::Enum(_, ref ast_generics) => {
                 if !ast_generics.params.is_empty() {
                     return;
                 }
                 let def = cx.tcx.adt_def(item.owner_id);
-                (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
+                (def, cx.tcx.mk_adt(def, ty::List::empty()))
             }
             _ => return,
         };
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 2070ffe..35dc533 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -63,6 +63,7 @@
 mod let_underscore;
 mod levels;
 mod lints;
+mod map_unit_fn;
 mod methods;
 mod multiple_supertrait_upcastable;
 mod non_ascii_idents;
@@ -100,6 +101,7 @@
 use hidden_unicode_codepoints::*;
 use internal::*;
 use let_underscore::*;
+use map_unit_fn::*;
 use methods::*;
 use multiple_supertrait_upcastable::*;
 use non_ascii_idents::*;
@@ -239,6 +241,7 @@
             NamedAsmLabels: NamedAsmLabels,
             OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
             MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
+            MapUnitFn: MapUnitFn,
         ]
     ]
 );
@@ -298,7 +301,8 @@
         UNUSED_LABELS,
         UNUSED_PARENS,
         UNUSED_BRACES,
-        REDUNDANT_SEMICOLONS
+        REDUNDANT_SEMICOLONS,
+        MAP_UNIT_FN
     );
 
     add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 2d9aa90..20ab0af 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -748,6 +748,22 @@
     }
 }
 
+// map_unit_fn.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_map_unit_fn)]
+#[note]
+pub struct MappingToUnit {
+    #[label(lint_function_label)]
+    pub function_label: Span,
+    #[label(lint_argument_label)]
+    pub argument_label: Span,
+    #[label(lint_map_label)]
+    pub map_label: Span,
+    #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")]
+    pub suggestion: Span,
+    pub replace: String,
+}
+
 // internal.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_default_hash_types)]
diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs
new file mode 100644
index 0000000..62e8b4f
--- /dev/null
+++ b/compiler/rustc_lint/src/map_unit_fn.rs
@@ -0,0 +1,120 @@
+use crate::lints::MappingToUnit;
+use crate::{LateContext, LateLintPass, LintContext};
+
+use rustc_hir::{Expr, ExprKind, HirId, Stmt, StmtKind};
+use rustc_middle::{
+    query::Key,
+    ty::{self, Ty},
+};
+
+declare_lint! {
+    /// The `map_unit_fn` lint checks for `Iterator::map` receive
+    /// a callable that returns `()`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// fn foo(items: &mut Vec<u8>) {
+    ///     items.sort();
+    /// }
+    ///
+    /// fn main() {
+    ///     let mut x: Vec<Vec<u8>> = vec![
+    ///         vec![0, 2, 1],
+    ///         vec![5, 4, 3],
+    ///     ];
+    ///     x.iter_mut().map(foo);
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Mapping to `()` is almost always a mistake.
+    pub MAP_UNIT_FN,
+    Warn,
+    "`Iterator::map` call that discard the iterator's values"
+}
+
+declare_lint_pass!(MapUnitFn => [MAP_UNIT_FN]);
+
+impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
+    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) {
+        if stmt.span.from_expansion() {
+            return;
+        }
+
+        if let StmtKind::Semi(expr) = stmt.kind {
+            if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind {
+                if path.ident.name.as_str() == "map" {
+                    if receiver.span.from_expansion()
+                        || args.iter().any(|e| e.span.from_expansion())
+                        || !is_impl_slice(cx, receiver)
+                        || !is_diagnostic_name(cx, expr.hir_id, "IteratorMap")
+                    {
+                        return;
+                    }
+                    let arg_ty = cx.typeck_results().expr_ty(&args[0]);
+                    if let ty::FnDef(id, _) = arg_ty.kind() {
+                        let fn_ty = cx.tcx.fn_sig(id).skip_binder();
+                        let ret_ty = fn_ty.output().skip_binder();
+                        if is_unit_type(ret_ty) {
+                            cx.emit_spanned_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx.tcx.span_of_impl(*id).unwrap(),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
+                        }
+                    } else if let ty::Closure(id, subs) = arg_ty.kind() {
+                        let cl_ty = subs.as_closure().sig();
+                        let ret_ty = cl_ty.output().skip_binder();
+                        if is_unit_type(ret_ty) {
+                            cx.emit_spanned_lint(
+                                MAP_UNIT_FN,
+                                span,
+                                MappingToUnit {
+                                    function_label: cx.tcx.span_of_impl(*id).unwrap(),
+                                    argument_label: args[0].span,
+                                    map_label: arg_ty.default_span(cx.tcx),
+                                    suggestion: path.ident.span,
+                                    replace: "for_each".to_string(),
+                                },
+                            )
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+fn is_impl_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
+        if let Some(impl_id) = cx.tcx.impl_of_method(method_id) {
+            return cx.tcx.type_of(impl_id).skip_binder().is_slice();
+        }
+    }
+    false
+}
+
+fn is_unit_type(ty: Ty<'_>) -> bool {
+    ty.is_unit() || ty.is_never()
+}
+
+fn is_diagnostic_name(cx: &LateContext<'_>, id: HirId, name: &str) -> bool {
+    if let Some(def_id) = cx.typeck_results().type_dependent_def_id(id) {
+        if let Some(item) = cx.tcx.get_diagnostic_name(def_id) {
+            if item.as_str() == name {
+                return true;
+            }
+        }
+    }
+    false
+}
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index d823989..5a4d358 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -502,7 +502,7 @@
                 .subst_identity()
                 .fn_sig(self.tcx)
                 .inputs()
-                .map_bound(|slice| self.tcx.intern_type_list(slice)),
+                .map_bound(|slice| self.tcx.mk_type_list(slice)),
         );
 
         argument_types
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 3457e51..b1e59b0 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -910,7 +910,7 @@
             std::iter::once(self.get_variant(&kind, item_id, did)).collect()
         };
 
-        tcx.alloc_adt_def(did, adt_kind, variants, repr)
+        tcx.mk_adt_def(did, adt_kind, variants, repr)
     }
 
     fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index e134ef8..8712514 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -47,7 +47,7 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_canonical_var_infos(v))
     }
 }
 
@@ -342,7 +342,7 @@
         infos: CanonicalVarInfos<'tcx>,
     ) -> CanonicalVarValues<'tcx> {
         CanonicalVarValues {
-            var_values: tcx.mk_substs(infos.iter().enumerate().map(
+            var_values: tcx.mk_substs_from_iter(infos.iter().enumerate().map(
                 |(i, info)| -> ty::GenericArg<'tcx> {
                     match info.kind {
                         CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index ccd8a33..0d78c61 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1620,7 +1620,7 @@
             &v
         };
 
-        Place { local: self.local, projection: tcx.intern_place_elems(new_projections) }
+        Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
     }
 }
 
@@ -2530,13 +2530,14 @@
         {
             InternalSubsts::identity_for_item(tcx, parent_did.to_def_id())
         } else {
-            tcx.intern_substs(&[])
+            List::empty()
         };
         debug!(?parent_substs);
 
         let did = def.did.to_def_id();
         let child_substs = InternalSubsts::identity_for_item(tcx, did);
-        let substs = tcx.mk_substs(parent_substs.into_iter().chain(child_substs.into_iter()));
+        let substs =
+            tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter()));
         debug!(?substs);
 
         let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index aa9f170..0aa2c50 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -194,14 +194,16 @@
                 let lhs_ty = lhs.ty(local_decls, tcx);
                 let rhs_ty = rhs.ty(local_decls, tcx);
                 let ty = op.ty(tcx, lhs_ty, rhs_ty);
-                tcx.intern_tup(&[ty, tcx.types.bool])
+                tcx.mk_tup(&[ty, tcx.types.bool])
             }
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
-                AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))),
+                AggregateKind::Tuple => {
+                    tcx.mk_tup_from_iter(ops.iter().map(|op| op.ty(local_decls, tcx)))
+                }
                 AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs),
                 AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs),
                 AggregateKind::Generator(did, substs, movability) => {
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index d0936d9..9881583 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -53,6 +53,6 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_place_elems(v))
     }
 }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 7f0935f..5c056b2 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1045,7 +1045,7 @@
             self.visit_local(&mut place.local, context, location);
 
             if let Some(new_projection) = self.process_projection(&place.projection, location) {
-                place.projection = self.tcx().intern_place_elems(&new_projection);
+                place.projection = self.tcx().mk_place_elems(&new_projection);
             }
         }
 
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index aadbce9..c5bf971 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -30,20 +30,18 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        Ok(FallibleTypeFolder::interner(folder).intern_external_constraints(
-            ExternalConstraintsData {
-                regions: (),
-                opaque_types: self
-                    .opaque_types
-                    .iter()
-                    .map(|opaque| opaque.try_fold_with(folder))
-                    .collect::<Result<_, F::Error>>()?,
-            },
-        ))
+        Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
+            regions: (),
+            opaque_types: self
+                .opaque_types
+                .iter()
+                .map(|opaque| opaque.try_fold_with(folder))
+                .collect::<Result<_, F::Error>>()?,
+        }))
     }
 
     fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
-        TypeFolder::interner(folder).intern_external_constraints(ExternalConstraintsData {
+        TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData {
             regions: (),
             opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
         })
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index f127b62..ec21030 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -54,7 +54,7 @@
 
 /// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`.
 ///
-/// These are all interned (by `alloc_adt_def`) into the global arena.
+/// These are all interned (by `mk_adt_def`) into the global arena.
 ///
 /// The initialism *ADT* stands for an [*algebraic data type (ADT)*][adt].
 /// This is slightly wrong because `union`s are not ADTs.
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index b9a1e23..3ce80e0 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -207,7 +207,7 @@
             })
         } else {
             let tcx = decoder.interner();
-            tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder))
+            tcx.mk_ty_from_kind(rustc_type_ir::TyKind::decode(decoder))
         }
     }
 }
@@ -244,7 +244,7 @@
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
         let tcx = decoder.interner();
-        tcx.mk_substs(
+        tcx.mk_substs_from_iter(
             (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -254,7 +254,7 @@
     fn decode(decoder: &mut D) -> Self {
         let local: mir::Local = Decodable::decode(decoder);
         let len = decoder.read_usize();
-        let projection = decoder.interner().mk_place_elems(
+        let projection = decoder.interner().mk_place_elems_from_iter(
             (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
         );
         mir::Place { local, projection }
@@ -263,16 +263,16 @@
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Region<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().mk_region(Decodable::decode(decoder))
+        decoder.interner().mk_region_from_kind(Decodable::decode(decoder))
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CanonicalVarInfos<'tcx> {
     fn decode(decoder: &mut D) -> Self {
         let len = decoder.read_usize();
-        let interned: Vec<CanonicalVarInfo<'tcx>> =
-            (0..len).map(|_| Decodable::decode(decoder)).collect();
-        decoder.interner().intern_canonical_var_infos(interned.as_slice())
+        decoder.interner().mk_canonical_var_infos_from_iter(
+            (0..len).map::<CanonicalVarInfo<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
@@ -310,7 +310,9 @@
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
+        decoder
+            .interner()
+            .mk_type_list_from_iter((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
     }
 }
 
@@ -319,7 +321,7 @@
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_poly_existential_predicates(
+        decoder.interner().mk_poly_existential_predicates_from_iter(
             (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -342,13 +344,13 @@
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ConstAllocation<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().intern_const_alloc(Decodable::decode(decoder))
+        decoder.interner().mk_const_alloc(Decodable::decode(decoder))
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AdtDef<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().intern_adt_def(Decodable::decode(decoder))
+        decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder))
     }
 }
 
@@ -375,7 +377,7 @@
 {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder.interner().mk_bound_variable_kinds(
+        decoder.interner().mk_bound_variable_kinds_from_iter(
             (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
         )
     }
@@ -384,18 +386,18 @@
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Const<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        decoder
-            .interner()
-            .mk_const_list((0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)))
+        decoder.interner().mk_const_list_from_iter(
+            (0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Predicate<'tcx>> {
     fn decode(decoder: &mut D) -> &'tcx Self {
         let len = decoder.read_usize();
-        let predicates: Vec<_> =
-            (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)).collect();
-        decoder.interner().intern_predicates(&predicates)
+        decoder.interner().mk_predicates_from_iter(
+            (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)),
+        )
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 796daa7..212dec9 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -6,7 +6,7 @@
 
 use crate::arena::Arena;
 use crate::dep_graph::{DepGraph, DepKindStruct};
-use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
+use crate::infer::canonical::CanonicalVarInfo;
 use crate::lint::struct_lint_level;
 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::resolve_bound_vars;
@@ -177,7 +177,7 @@
         }
     }
 
-    /// Interns a type.
+    /// Interns a type. (Use `mk_*` functions instead, where possible.)
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline(never)]
     fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> {
@@ -217,6 +217,7 @@
         }
     }
 
+    /// Interns a predicate. (Use `mk_predicate` instead, where possible.)
     #[inline(never)]
     fn intern_predicate(
         &self,
@@ -615,21 +616,21 @@
         self.arena.alloc(Steal::new(promoted))
     }
 
-    pub fn alloc_adt_def(
+    pub fn mk_adt_def(
         self,
         did: DefId,
         kind: AdtKind,
         variants: IndexVec<VariantIdx, ty::VariantDef>,
         repr: ReprOptions,
     ) -> ty::AdtDef<'tcx> {
-        self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr))
+        self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr))
     }
 
     /// Allocates a read-only byte or string literal for `mir::interpret`.
     pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
         // Create an allocation that just contains these bytes.
         let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
-        let alloc = self.intern_const_alloc(alloc);
+        let alloc = self.mk_const_alloc(alloc);
         self.create_memory_alloc(alloc)
     }
 
@@ -719,7 +720,7 @@
     /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
     #[track_caller]
     pub fn ty_error(self, reported: ErrorGuaranteed) -> Ty<'tcx> {
-        self.mk_ty(Error(reported))
+        self.mk_ty_from_kind(Error(reported))
     }
 
     /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used.
@@ -733,7 +734,7 @@
     #[track_caller]
     pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> {
         let reported = self.sess.delay_span_bug(span, msg);
-        self.mk_ty(Error(reported))
+        self.mk_ty_from_kind(Error(reported))
     }
 
     /// Constructs a `RegionKind::ReError` lifetime.
@@ -1194,7 +1195,7 @@
         self.mk_imm_ref(
             self.lifetimes.re_static,
             self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
-                .subst(self, self.intern_substs(&[self.lifetimes.re_static.into()])),
+                .subst(self, self.mk_substs(&[self.lifetimes.re_static.into()])),
         )
     }
 
@@ -1276,7 +1277,7 @@
 
 // Can't use the macros as we have reuse the `substs` here.
 //
-// See `intern_type_list` for more info.
+// See `mk_type_list` for more info.
 impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> {
     type Lifted = &'tcx List<Ty<'tcx>>;
     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
@@ -1517,7 +1518,7 @@
 }
 
 macro_rules! direct_interners {
-    ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
+    ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
         $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
             fn borrow<'a>(&'a self) -> &'a $ty {
                 &self.0
@@ -1543,7 +1544,7 @@
         }
 
         impl<'tcx> TyCtxt<'tcx> {
-            pub fn $method(self, v: $ty) -> $ret_ty {
+            $vis fn $method(self, v: $ty) -> $ret_ty {
                 $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
                     InternedInSet(self.interners.arena.alloc(v))
                 }).0))
@@ -1552,37 +1553,47 @@
     }
 }
 
+// Functions with a `mk_` prefix are intended for use outside this file and
+// crate. Functions with an `intern_` prefix are intended for use within this
+// file only, and have a corresponding `mk_` function.
 direct_interners! {
     region: intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
-    const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>,
-    const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
-    layout: intern_layout(LayoutS): Layout -> Layout<'tcx>,
-    adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
-    external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>,
+    const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>,
+    const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
+    layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>,
+    adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
+    external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>):
+        ExternalConstraints -> ExternalConstraints<'tcx>,
 }
 
 macro_rules! slice_interners {
-    ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
+    ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => (
         impl<'tcx> TyCtxt<'tcx> {
-            $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
-                self.interners.$field.intern_ref(v, || {
-                    InternedInSet(List::from_arena(&*self.arena, v))
-                }).0
+            $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
+                if v.is_empty() {
+                    List::empty()
+                } else {
+                    self.interners.$field.intern_ref(v, || {
+                        InternedInSet(List::from_arena(&*self.arena, v))
+                    }).0
+                }
             })+
         }
     );
 }
 
+// These functions intern slices. They all have a corresponding
+// `mk_foo_from_iter` function that interns an iterator. The slice version
+// should be used when possible, because it's faster.
 slice_interners!(
-    const_lists: _intern_const_list(Const<'tcx>),
-    substs: _intern_substs(GenericArg<'tcx>),
-    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
-    poly_existential_predicates:
-        _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
-    predicates: _intern_predicates(Predicate<'tcx>),
-    projs: _intern_projs(ProjectionKind),
-    place_elems: _intern_place_elems(PlaceElem<'tcx>),
-    bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
+    const_lists: pub mk_const_list(Const<'tcx>),
+    substs: pub mk_substs(GenericArg<'tcx>),
+    canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>),
+    poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>),
+    predicates: intern_predicates(Predicate<'tcx>),
+    projs: pub mk_projs(ProjectionKind),
+    place_elems: pub mk_place_elems(PlaceElem<'tcx>),
+    bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
 );
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -1670,7 +1681,7 @@
     // Avoid this in favour of more specific `mk_*` methods, where possible.
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline]
-    pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
+    pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> {
         self.interners.intern_ty(
             st,
             self.sess,
@@ -1735,12 +1746,12 @@
     #[inline]
     pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
         // Take a copy of substs so that we own the vectors inside.
-        self.mk_ty(Adt(def, substs))
+        self.mk_ty_from_kind(Adt(def, substs))
     }
 
     #[inline]
     pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
-        self.mk_ty(Foreign(def_id))
+        self.mk_ty_from_kind(Foreign(def_id))
     }
 
     fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> {
@@ -1757,7 +1768,7 @@
                     }
                 }
             });
-        self.mk_ty(Adt(adt_def, substs))
+        self.mk_ty_from_kind(Adt(adt_def, substs))
     }
 
     #[inline]
@@ -1786,12 +1797,12 @@
 
     #[inline]
     pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(RawPtr(tm))
+        self.mk_ty_from_kind(RawPtr(tm))
     }
 
     #[inline]
     pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Ref(r, tm.ty, tm.mutbl))
+        self.mk_ty_from_kind(Ref(r, tm.ty, tm.mutbl))
     }
 
     #[inline]
@@ -1816,30 +1827,34 @@
 
     #[inline]
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, ty::Const::from_target_usize(self, n)))
+        self.mk_ty_from_kind(Array(ty, ty::Const::from_target_usize(self, n)))
     }
 
     #[inline]
     pub fn mk_array_with_const_len(self, ty: Ty<'tcx>, ct: Const<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, ct))
+        self.mk_ty_from_kind(Array(ty, ct))
     }
 
     #[inline]
     pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Slice(ty))
+        self.mk_ty_from_kind(Slice(ty))
     }
 
     #[inline]
-    pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
-        if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) }
+    pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
+        if ts.is_empty() {
+            self.types.unit
+        } else {
+            self.mk_ty_from_kind(Tuple(self.mk_type_list(&ts)))
+        }
     }
 
-    pub fn mk_tup<I, T>(self, iter: I) -> T::Output
+    pub fn mk_tup_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>,
     {
-        T::collect_and_apply(iter, |ts| self.intern_tup(ts))
+        T::collect_and_apply(iter, |ts| self.mk_tup(ts))
     }
 
     #[inline]
@@ -1858,12 +1873,12 @@
         def_id: DefId,
         substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
-        let substs = self.check_substs(def_id, substs);
-        self.mk_ty(FnDef(def_id, substs))
+        let substs = self.check_and_mk_substs(def_id, substs);
+        self.mk_ty_from_kind(FnDef(def_id, substs))
     }
 
     #[inline(always)]
-    fn check_substs(
+    fn check_and_mk_substs(
         self,
         _def_id: DefId,
         substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
@@ -1879,12 +1894,12 @@
                 substs.collect::<Vec<_>>(),
             );
         }
-        self.mk_substs(substs)
+        self.mk_substs_from_iter(substs)
     }
 
     #[inline]
     pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(FnPtr(fty))
+        self.mk_ty_from_kind(FnPtr(fty))
     }
 
     #[inline]
@@ -1894,7 +1909,7 @@
         reg: ty::Region<'tcx>,
         repr: DynKind,
     ) -> Ty<'tcx> {
-        self.mk_ty(Dynamic(obj, reg, repr))
+        self.mk_ty_from_kind(Dynamic(obj, reg, repr))
     }
 
     #[inline]
@@ -1908,7 +1923,7 @@
 
     #[inline]
     pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Closure(closure_id, closure_substs))
+        self.mk_ty_from_kind(Closure(closure_id, closure_substs))
     }
 
     #[inline]
@@ -1918,47 +1933,51 @@
         generator_substs: SubstsRef<'tcx>,
         movability: hir::Movability,
     ) -> Ty<'tcx> {
-        self.mk_ty(Generator(id, generator_substs, movability))
+        self.mk_ty_from_kind(Generator(id, generator_substs, movability))
     }
 
     #[inline]
     pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
-        self.mk_ty(GeneratorWitness(types))
+        self.mk_ty_from_kind(GeneratorWitness(types))
     }
 
     /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
     pub fn mk_task_context(self) -> Ty<'tcx> {
         let context_did = self.require_lang_item(LangItem::Context, None);
         let context_adt_ref = self.adt_def(context_did);
-        let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]);
+        let context_substs = self.mk_substs(&[self.lifetimes.re_erased.into()]);
         let context_ty = self.mk_adt(context_adt_ref, context_substs);
         self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
     }
 
     #[inline]
     pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(GeneratorWitnessMIR(id, substs))
+        self.mk_ty_from_kind(GeneratorWitnessMIR(id, substs))
     }
 
     #[inline]
     pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> {
-        self.mk_const_internal(ty::ConstData { kind: kind.into(), ty })
+        self.intern_const(ty::ConstData { kind: kind.into(), ty })
     }
 
     #[inline]
     pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
         // Use a pre-interned one when possible.
-        self.types.ty_vars.get(v.as_usize()).copied().unwrap_or_else(|| self.mk_ty(Infer(TyVar(v))))
+        self.types
+            .ty_vars
+            .get(v.as_usize())
+            .copied()
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(TyVar(v))))
     }
 
     #[inline]
     pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> {
-        self.mk_ty(Infer(IntVar(v)))
+        self.mk_ty_from_kind(Infer(IntVar(v)))
     }
 
     #[inline]
     pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> {
-        self.mk_ty(Infer(FloatVar(v)))
+        self.mk_ty_from_kind(Infer(FloatVar(v)))
     }
 
     #[inline]
@@ -1968,7 +1987,7 @@
             .fresh_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshTy(n))))
     }
 
     #[inline]
@@ -1978,7 +1997,7 @@
             .fresh_int_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshIntTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshIntTy(n))))
     }
 
     #[inline]
@@ -1988,12 +2007,12 @@
             .fresh_float_tys
             .get(n as usize)
             .copied()
-            .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshFloatTy(n))))
+            .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshFloatTy(n))))
     }
 
     #[inline]
     pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> {
-        self.mk_ty(Param(ParamTy { index, name }))
+        self.mk_ty_from_kind(Param(ParamTy { index, name }))
     }
 
     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
@@ -2015,17 +2034,17 @@
 
     #[inline]
     pub fn mk_bound(self, index: ty::DebruijnIndex, bound_ty: ty::BoundTy) -> Ty<'tcx> {
-        self.mk_ty(Bound(index, bound_ty))
+        self.mk_ty_from_kind(Bound(index, bound_ty))
     }
 
     #[inline]
     pub fn mk_placeholder(self, placeholder: ty::PlaceholderType) -> Ty<'tcx> {
-        self.mk_ty(Placeholder(placeholder))
+        self.mk_ty_from_kind(Placeholder(placeholder))
     }
 
     #[inline]
     pub fn mk_alias(self, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> {
-        self.mk_ty(Alias(kind, alias_ty))
+        self.mk_ty_from_kind(Alias(kind, alias_ty))
     }
 
     #[inline]
@@ -2078,7 +2097,7 @@
 
     // Avoid this in favour of more specific `mk_re_*` methods, where possible,
     // to avoid the cost of the `match`.
-    pub fn mk_region(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> {
+    pub fn mk_region_from_kind(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> {
         match kind {
             ty::ReEarlyBound(region) => self.mk_re_early_bound(region),
             ty::ReLateBound(debruijn, region) => self.mk_re_late_bound(debruijn, region),
@@ -2132,10 +2151,10 @@
         let mut projection = place.projection.to_vec();
         projection.push(elem);
 
-        Place { local: place.local, projection: self.intern_place_elems(&projection) }
+        Place { local: place.local, projection: self.mk_place_elems(&projection) }
     }
 
-    pub fn intern_poly_existential_predicates(
+    pub fn mk_poly_existential_predicates(
         self,
         eps: &[PolyExistentialPredicate<'tcx>],
     ) -> &'tcx List<PolyExistentialPredicate<'tcx>> {
@@ -2145,80 +2164,40 @@
                 .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder())
                     != Ordering::Greater)
         );
-        self._intern_poly_existential_predicates(eps)
+        self.intern_poly_existential_predicates(eps)
     }
 
-    pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
+    pub fn mk_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> {
         // FIXME consider asking the input slice to be sorted to avoid
         // re-interning permutations, in which case that would be asserted
         // here.
-        if preds.is_empty() {
-            // The macro-generated method below asserts we don't intern an empty slice.
-            List::empty()
-        } else {
-            self._intern_predicates(preds)
-        }
+        self.intern_predicates(preds)
     }
 
-    pub fn mk_const_list<I, T>(self, iter: I) -> T::Output
+    pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_const_list(xs))
+        T::collect_and_apply(iter, |xs| self.mk_const_list(xs))
     }
 
-    pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> {
-        if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) }
+    pub fn mk_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
+        // Actually intern type lists as lists of `GenericArg`s.
+        //
+        // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
+        // as explained in ty_slice_as_generic_arg`. With this,
+        // we guarantee that even when transmuting between `List<Ty<'tcx>>`
+        // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
+        // lists is upheld.
+        let substs = self.mk_substs(ty::subst::ty_slice_as_generic_args(ts));
+        substs.try_as_type_list().unwrap()
     }
 
-    pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
-        if ts.is_empty() {
-            List::empty()
-        } else {
-            // Actually intern type lists as lists of `GenericArg`s.
-            //
-            // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound
-            // as explained in ty_slice_as_generic_arg`. With this,
-            // we guarantee that even when transmuting between `List<Ty<'tcx>>`
-            // and `List<GenericArg<'tcx>>`, the uniqueness requirement for
-            // lists is upheld.
-            let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts));
-            substs.try_as_type_list().unwrap()
-        }
-    }
-
-    pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> {
-        if ts.is_empty() { List::empty() } else { self._intern_substs(ts) }
-    }
-
-    pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> {
-        if ps.is_empty() { List::empty() } else { self._intern_projs(ps) }
-    }
-
-    pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> {
-        if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
-    }
-
-    pub fn intern_canonical_var_infos(
-        self,
-        ts: &[CanonicalVarInfo<'tcx>],
-    ) -> CanonicalVarInfos<'tcx> {
-        if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
-    }
-
-    pub fn intern_bound_variable_kinds(
-        self,
-        ts: &[ty::BoundVariableKind],
-    ) -> &'tcx List<ty::BoundVariableKind> {
-        if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
-    }
-
-    // Unlike various other `mk_*` functions, this one uses `I: IntoIterator`
-    // instead of `I: Iterator`. Unlike those other functions, this one doesn't
-    // have a `intern_fn_sig` variant that can be used for cases where `I` is
-    // something like a `Vec`. That's because of the need to combine `inputs`
-    // and `output`.
+    // Unlike various other `mk_*_from_iter` functions, this one uses `I:
+    // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
+    // variant, because of the need to combine `inputs` and `output`. This
+    // explains the lack of `_from_iter` suffix.
     pub fn mk_fn_sig<I, T>(
         self,
         inputs: I,
@@ -2232,14 +2211,14 @@
         T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
     {
         T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig {
-            inputs_and_output: self.intern_type_list(xs),
+            inputs_and_output: self.mk_type_list(xs),
             c_variadic,
             unsafety,
             abi,
         })
     }
 
-    pub fn mk_poly_existential_predicates<I, T>(self, iter: I) -> T::Output
+    pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<
@@ -2247,39 +2226,47 @@
                 &'tcx List<PolyExistentialPredicate<'tcx>>,
             >,
     {
-        T::collect_and_apply(iter, |xs| self.intern_poly_existential_predicates(xs))
+        T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs))
     }
 
-    pub fn mk_predicates<I, T>(self, iter: I) -> T::Output
+    pub fn mk_predicates_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_predicates(xs))
+        T::collect_and_apply(iter, |xs| self.mk_predicates(xs))
     }
 
-    pub fn mk_type_list<I, T>(self, iter: I) -> T::Output
+    pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_type_list(xs))
+        T::collect_and_apply(iter, |xs| self.mk_type_list(xs))
     }
 
-    pub fn mk_substs<I, T>(self, iter: I) -> T::Output
+    pub fn mk_substs_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_substs(xs))
+        T::collect_and_apply(iter, |xs| self.mk_substs(xs))
     }
 
-    pub fn mk_place_elems<I, T>(self, iter: I) -> T::Output
+    pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output
+    where
+        I: Iterator<Item = T>,
+        T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>,
+    {
+        T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs))
+    }
+
+    pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_place_elems(xs))
+        T::collect_and_apply(iter, |xs| self.mk_place_elems(xs))
     }
 
     pub fn mk_substs_trait(
@@ -2287,7 +2274,7 @@
         self_ty: Ty<'tcx>,
         rest: impl IntoIterator<Item = GenericArg<'tcx>>,
     ) -> SubstsRef<'tcx> {
-        self.mk_substs(iter::once(self_ty.into()).chain(rest))
+        self.mk_substs_from_iter(iter::once(self_ty.into()).chain(rest))
     }
 
     pub fn mk_trait_ref(
@@ -2295,7 +2282,7 @@
         trait_def_id: DefId,
         substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> ty::TraitRef<'tcx> {
-        let substs = self.check_substs(trait_def_id, substs);
+        let substs = self.check_and_mk_substs(trait_def_id, substs);
         ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () }
     }
 
@@ -2304,16 +2291,16 @@
         def_id: DefId,
         substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> ty::AliasTy<'tcx> {
-        let substs = self.check_substs(def_id, substs);
+        let substs = self.check_and_mk_substs(def_id, substs);
         ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () }
     }
 
-    pub fn mk_bound_variable_kinds<I, T>(self, iter: I) -> T::Output
+    pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
     where
         I: Iterator<Item = T>,
         T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
     {
-        T::collect_and_apply(iter, |xs| self.intern_bound_variable_kinds(xs))
+        T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs))
     }
 
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
@@ -2398,7 +2385,7 @@
     }
 
     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
-        self.intern_bound_variable_kinds(
+        self.mk_bound_variable_kinds(
             &self
                 .late_bound_vars_map(id.owner)
                 .and_then(|map| map.get(&id.local_id).cloned())
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index e8a7383..d66f436 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -422,7 +422,7 @@
         let mut map = Default::default();
         let delegate = Anonymize { tcx: self, map: &mut map };
         let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
-        let bound_vars = self.mk_bound_variable_kinds(map.into_values());
+        let bound_vars = self.mk_bound_variable_kinds_from_iter(map.into_values());
         Binder::bind_with_vars(inner, bound_vars)
     }
 }
diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs
index 3e59c0b..4c7822a 100644
--- a/compiler/rustc_middle/src/ty/impls_ty.rs
+++ b/compiler/rustc_middle/src/ty/impls_ty.rs
@@ -79,7 +79,7 @@
             // WARNING: We dedup cache the `HashStable` results for `List`
             // while ignoring types and freely transmute
             // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
-            // See `fn intern_type_list` for more details.
+            // See `fn mk_type_list` for more details.
             //
             // We therefore hash types without adding a hash for their discriminant.
             //
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index d07fa0e..f4028a5 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -540,7 +540,7 @@
 
     pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
         let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
-        let substs = tcx.intern_substs(&[ty.into()]);
+        let substs = tcx.mk_substs(&[ty.into()]);
         Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs)
     }
 
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 146803d..6c59cde 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -596,7 +596,7 @@
                     ty::Adt(def, _) => def.variant(variant_index).fields.len(),
                     _ => bug!(),
                 };
-                tcx.intern_layout(LayoutS {
+                tcx.mk_layout(LayoutS {
                     variants: Variants::Single { index: variant_index },
                     fields: match NonZeroUsize::new(fields) {
                         Some(fields) => FieldsShape::Union(fields),
@@ -609,7 +609,7 @@
                 })
             }
 
-            Variants::Multiple { ref variants, .. } => cx.tcx().intern_layout(variants[variant_index].clone()),
+            Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()),
         };
 
         assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
@@ -631,7 +631,7 @@
             let tcx = cx.tcx();
             let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
                 TyAndLayout {
-                    layout: tcx.intern_layout(LayoutS::scalar(cx, tag)),
+                    layout: tcx.mk_layout(LayoutS::scalar(cx, tag)),
                     ty: tag.primitive().to_ty(tcx),
                 }
             };
@@ -687,7 +687,7 @@
                         Increase this counter if you tried to implement this but
                         failed to do it without duplicating a lot of code from
                         other places in the compiler: 2
-                        tcx.intern_tup(&[
+                        tcx.mk_tup(&[
                             tcx.mk_array(tcx.types.usize, 3),
                             tcx.mk_array(Option<fn()>),
                         ])
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index c8b1c7f..17262a0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -757,7 +757,7 @@
         let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
         // 3) ['x] + ['b] -> ['x, 'b]
         let bound_vars =
-            tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars));
+            tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
         tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars))
     }
 }
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 6463b38..751f306 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -79,7 +79,7 @@
         // during codegen.
 
         let generics = self.tcx.generics_of(def_id);
-        self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| {
+        self.tcx.mk_substs_from_iter(substs.iter().enumerate().map(|(index, kind)| {
             if index < generics.parent_count {
                 // Accommodate missing regions in the parent kinds...
                 self.fold_kind_no_missing_regions_error(kind)
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 5b3f387..3d9a507 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -328,8 +328,9 @@
 
                 Providers {
                     $($name: |_, key| bug!(
-                        "`tcx.{}({:?})` is not supported for {} crate;\n
-                        hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.\n
+                        "`tcx.{}({:?})` is not supported for {} crate;\n\
+                        hint: Queries can be either made to the local crate, or the external crate. \
+                        This error means you tried to use it for one that's not supported.\n\
                         If that's not the case, {} was likely never assigned to a provider function.\n",
                         stringify!($name),
                         key,
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 735b87d..3fc5f5b 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -144,7 +144,7 @@
     a_subst: SubstsRef<'tcx>,
     b_subst: SubstsRef<'tcx>,
 ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
-    relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| {
+    relation.tcx().mk_substs_from_iter(iter::zip(a_subst, b_subst).map(|(a, b)| {
         relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
     }))
 }
@@ -171,7 +171,7 @@
         relation.relate_with_variance(variance, variance_info, a, b)
     });
 
-    tcx.mk_substs(params)
+    tcx.mk_substs_from_iter(params)
 }
 
 impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
@@ -222,7 +222,7 @@
                 r => r,
             });
         Ok(ty::FnSig {
-            inputs_and_output: tcx.mk_type_list(inputs_and_output)?,
+            inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?,
             c_variadic: a.c_variadic,
             unsafety,
             abi,
@@ -352,7 +352,8 @@
     ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
         assert_eq!(a.0.len(), b.0.len());
         let tcx = relation.tcx();
-        let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
+        let types =
+            tcx.mk_type_list_from_iter(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
         Ok(GeneratorWitness(types))
     }
 }
@@ -528,7 +529,7 @@
 
         (&ty::Tuple(as_), &ty::Tuple(bs)) => {
             if as_.len() == bs.len() {
-                Ok(tcx.mk_tup(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?)
+                Ok(tcx.mk_tup_from_iter(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?)
             } else if !(as_.is_empty() || bs.is_empty()) {
                 Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len())))
             } else {
@@ -673,7 +674,7 @@
                     for (a_arg, b_arg) in aa.iter().zip(ba.iter()) {
                         related_args.push(r.consts(a_arg, b_arg)?);
                     }
-                    let related_args = tcx.intern_const_list(&related_args);
+                    let related_args = tcx.mk_const_list(&related_args);
                     Expr::FunctionCall(func, related_args)
                 }
                 _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))),
@@ -720,7 +721,7 @@
                 _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
             }
         });
-        tcx.mk_poly_existential_predicates(v)
+        tcx.mk_poly_existential_predicates_from_iter(v)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index fbe5d8c..1d4d76d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -430,7 +430,7 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_poly_existential_predicates(v))
     }
 }
 
@@ -439,7 +439,7 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_const_list(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v))
     }
 }
 
@@ -448,7 +448,7 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_projs(v))
     }
 }
 
@@ -513,7 +513,7 @@
             | ty::Foreign(..) => return Ok(self),
         };
 
-        Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty(kind) })
+        Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty_from_kind(kind) })
     }
 }
 
@@ -636,7 +636,7 @@
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
+        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_predicates(v))
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 658f09a..ba71454 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -250,7 +250,7 @@
         parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
     ) -> ClosureSubsts<'tcx> {
         ClosureSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(
                     [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
                         .iter()
@@ -377,7 +377,7 @@
         parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
     ) -> GeneratorSubsts<'tcx> {
         GeneratorSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(
                     [
                         parts.resume_ty,
@@ -655,7 +655,7 @@
         parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
     ) -> InlineConstSubsts<'tcx> {
         InlineConstSubsts {
-            substs: tcx.mk_substs(
+            substs: tcx.mk_substs_from_iter(
                 parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
             ),
         }
@@ -853,7 +853,7 @@
         substs: SubstsRef<'tcx>,
     ) -> ty::TraitRef<'tcx> {
         let defs = tcx.generics_of(trait_id);
-        tcx.mk_trait_ref(trait_id, tcx.intern_substs(&substs[..defs.params.len()]))
+        tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()]))
     }
 }
 
@@ -899,7 +899,7 @@
 
         ty::ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            substs: tcx.intern_substs(&trait_ref.substs[1..]),
+            substs: tcx.mk_substs(&trait_ref.substs[1..]),
         }
     }
 
@@ -1551,7 +1551,7 @@
     pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
         let def_id = tcx.parent(self.def_id);
         let subst_count = tcx.generics_of(def_id).count() - 1;
-        let substs = tcx.intern_substs(&self.substs[..subst_count]);
+        let substs = tcx.mk_substs(&self.substs[..subst_count]);
         ty::ExistentialTraitRef { def_id, substs }
     }
 
@@ -1579,7 +1579,7 @@
 
         Self {
             def_id: projection_predicate.projection_ty.def_id,
-            substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
+            substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]),
             term: projection_predicate.term,
         }
     }
@@ -2209,7 +2209,7 @@
                 let assoc_items = tcx.associated_item_def_ids(
                     tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
                 );
-                tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()]))
+                tcx.mk_projection(assoc_items[0], tcx.mk_substs(&[self.into()]))
             }
 
             ty::Bool
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 1ed3ef5..b090bd9 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -71,7 +71,7 @@
     /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`.
     ///
     /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have
-    /// be interned together, see `intern_type_list` for more details.
+    /// be interned together, see `mk_type_list` for more details.
     #[inline]
     pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> {
         assert_eq!(TYPE_TAG, 0);
@@ -319,7 +319,7 @@
         let count = defs.count();
         let mut substs = SmallVec::with_capacity(count);
         Self::fill_item(&mut substs, tcx, defs, &mut mk_kind);
-        tcx.intern_substs(&substs)
+        tcx.mk_substs(&substs)
     }
 
     pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
@@ -468,11 +468,11 @@
         target_substs: SubstsRef<'tcx>,
     ) -> SubstsRef<'tcx> {
         let defs = tcx.generics_of(source_ancestor);
-        tcx.mk_substs(target_substs.iter().chain(self.iter().skip(defs.params.len())))
+        tcx.mk_substs_from_iter(target_substs.iter().chain(self.iter().skip(defs.params.len())))
     }
 
     pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
-        tcx.mk_substs(self.iter().take(generics.count()))
+        tcx.mk_substs_from_iter(self.iter().take(generics.count()))
     }
 }
 
@@ -486,14 +486,14 @@
         // The match arms are in order of frequency. The 1, 2, and 0 cases are
         // typically hit in 90--99.99% of cases. When folding doesn't change
         // the substs, it's faster to reuse the existing substs rather than
-        // calling `intern_substs`.
+        // calling `mk_substs`.
         match self.len() {
             1 => {
                 let param0 = self[0].try_fold_with(folder)?;
                 if param0 == self[0] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_substs(&[param0]))
+                    Ok(folder.interner().mk_substs(&[param0]))
                 }
             }
             2 => {
@@ -502,11 +502,11 @@
                 if param0 == self[0] && param1 == self[1] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_substs(&[param0, param1]))
+                    Ok(folder.interner().mk_substs(&[param0, param1]))
                 }
             }
             0 => Ok(self),
-            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_substs(v)),
+            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_substs(v)),
         }
     }
 }
@@ -538,10 +538,10 @@
                 if param0 == self[0] && param1 == self[1] {
                     Ok(self)
                 } else {
-                    Ok(folder.interner().intern_type_list(&[param0, param1]))
+                    Ok(folder.interner().mk_type_list(&[param0, param1]))
                 }
             }
-            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)),
+            _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs
index f77bd9f..b9b1cd7 100644
--- a/compiler/rustc_middle/src/ty/vtable.rs
+++ b/compiler/rustc_middle/src/ty/vtable.rs
@@ -112,5 +112,5 @@
     }
 
     vtable.mutability = Mutability::Not;
-    tcx.create_memory_alloc(tcx.intern_const_alloc(vtable))
+    tcx.create_memory_alloc(tcx.mk_const_alloc(vtable))
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 1d96893..2f63333 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -132,14 +132,14 @@
         (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
             let s = s.as_str();
             let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
-            let allocation = tcx.intern_const_alloc(allocation);
+            let allocation = tcx.mk_const_alloc(allocation);
             ConstValue::Slice { data: allocation, start: 0, end: s.len() }
         }
         (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _))
             if matches!(inner_ty.kind(), ty::Slice(_)) =>
         {
             let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
-            let allocation = tcx.intern_const_alloc(allocation);
+            let allocation = tcx.mk_const_alloc(allocation);
             ConstValue::Slice { data: allocation, start: 0, end: data.len() }
         }
         (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index c621efb..ff31988 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -170,7 +170,7 @@
                     // Return the operand *tmp0 to be used as the call argument
                     let place = Place {
                         local: operand,
-                        projection: tcx.intern_place_elems(&[PlaceElem::Deref]),
+                        projection: tcx.mk_place_elems(&[PlaceElem::Deref]),
                     };
 
                     return block.and(Operand::Move(place));
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index e22fa63..eb20b23 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -263,7 +263,7 @@
         let resolved = self.resolve_upvar(cx);
         let builder = resolved.as_ref().unwrap_or(self);
         let PlaceBase::Local(local) = builder.base else { return None };
-        let projection = cx.tcx.intern_place_elems(&builder.projection);
+        let projection = cx.tcx.mk_place_elems(&builder.projection);
         Some(Place { local, projection })
     }
 
@@ -692,7 +692,7 @@
                             tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
                         let fake_borrow_temp =
                             self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
-                        let projection = tcx.intern_place_elems(&base_place.projection[..idx]);
+                        let projection = tcx.mk_place_elems(&base_place.projection[..idx]);
                         self.cfg.push_assign(
                             block,
                             source_info,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index fb0e918..a4e48c1 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -520,7 +520,7 @@
         let source_info = self.source_info(span);
         let bool_ty = self.tcx.types.bool;
         if self.check_overflow && op.is_checkable() && ty.is_integral() {
-            let result_tup = self.tcx.intern_tup(&[ty, bool_ty]);
+            let result_tup = self.tcx.mk_tup(&[ty, bool_ty]);
             let result_value = self.temp(result_tup, span);
 
             self.cfg.push_assign(
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 6b960eb..de2851a 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1206,7 +1206,7 @@
 
                     fake_borrows.insert(Place {
                         local: source.local,
-                        projection: self.tcx.intern_place_elems(proj_base),
+                        projection: self.tcx.mk_place_elems(proj_base),
                     });
                 }
             }
@@ -1743,7 +1743,7 @@
             .map(|matched_place_ref| {
                 let matched_place = Place {
                     local: matched_place_ref.local,
-                    projection: tcx.intern_place_elems(matched_place_ref.projection),
+                    projection: tcx.mk_place_elems(matched_place_ref.projection),
                 };
                 let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty;
                 let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 27536fc..a6de8684 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -859,7 +859,7 @@
 
                     let use_place = Place {
                         local: ty::CAPTURE_STRUCT_LOCAL,
-                        projection: tcx.intern_place_elems(&projs),
+                        projection: tcx.mk_place_elems(&projs),
                     };
                     self.var_debug_info.push(VarDebugInfo {
                         name: *sym,
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 261b95b..3b11fc7 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -307,7 +307,7 @@
 
                     let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
                     let tupled_args = Expr {
-                        ty: tcx.mk_tup(arg_tys),
+                        ty: tcx.mk_tup_from_iter(arg_tys),
                         temp_lifetime,
                         span: expr.span,
                         kind: ExprKind::Tuple { fields: self.mirror_exprs(args) },
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 74c35ef..20af60a 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -133,9 +133,8 @@
                     bug!("closure expr does not have closure type: {:?}", closure_ty);
                 };
 
-                let bound_vars = self
-                    .tcx
-                    .intern_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
+                let bound_vars =
+                    self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]);
                 let br = ty::BoundRegion {
                     var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                     kind: ty::BrEnv,
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 077a21f..2ae3ae0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -1,4 +1,3 @@
-use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets};
 use rustc_middle::ty::TyCtxt;
 use std::ops::RangeInclusive;
@@ -54,7 +53,6 @@
         analysis: &A,
         tcx: TyCtxt<'tcx>,
         body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         block: (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -221,7 +219,6 @@
         analysis: &A,
         _tcx: TyCtxt<'tcx>,
         body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         (bb, _bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -278,20 +275,6 @@
                     }
                 }
 
-                // Ignore dead unwinds.
-                mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
-                | mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
-                | mir::TerminatorKind::Drop { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::DropAndReplace { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::FalseUnwind { unwind: Some(unwind), .. }
-                | mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. }
-                    if unwind == bb =>
-                {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) {
-                        propagate(pred, exit_state);
-                    }
-                }
-
                 _ => propagate(pred, exit_state),
             }
         }
@@ -304,7 +287,6 @@
     exit_state: &'a mut D,
     bb: BasicBlock,
     propagate: &'a mut F,
-
     effects_applied: bool,
 }
 
@@ -484,7 +466,6 @@
         analysis: &A,
         _tcx: TyCtxt<'tcx>,
         _body: &mir::Body<'tcx>,
-        dead_unwinds: Option<&BitSet<BasicBlock>>,
         exit_state: &mut A::Domain,
         (bb, bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
         mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -502,9 +483,7 @@
             | DropAndReplace { target, unwind, value: _, place: _ }
             | FalseUnwind { real_target: target, unwind } => {
                 if let Some(unwind) = unwind {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 propagate(target, exit_state);
@@ -534,9 +513,7 @@
                 fn_span: _,
             } => {
                 if let Some(unwind) = cleanup {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 if let Some(target) = target {
@@ -560,9 +537,7 @@
                 cleanup,
             } => {
                 if let Some(unwind) = cleanup {
-                    if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
-                        propagate(unwind, exit_state);
-                    }
+                    propagate(unwind, exit_state);
                 }
 
                 if let Some(target) = destination {
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 6ddbe69..91c3bf0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -12,7 +12,6 @@
 use rustc_data_structures::work_queue::WorkQueue;
 use rustc_graphviz as dot;
 use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::{self, traversal, BasicBlock};
 use rustc_middle::mir::{create_dump_file, dump_enabled};
@@ -78,7 +77,6 @@
 {
     tcx: TyCtxt<'tcx>,
     body: &'a mir::Body<'tcx>,
-    dead_unwinds: Option<&'a BitSet<BasicBlock>>,
     entry_sets: IndexVec<BasicBlock, A::Domain>,
     pass_name: Option<&'static str>,
     analysis: A,
@@ -154,25 +152,7 @@
             bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
         }
 
-        Engine {
-            analysis,
-            tcx,
-            body,
-            dead_unwinds: None,
-            pass_name: None,
-            entry_sets,
-            apply_trans_for_block,
-        }
-    }
-
-    /// Signals that we do not want dataflow state to propagate across unwind edges for these
-    /// `BasicBlock`s.
-    ///
-    /// You must take care that `dead_unwinds` does not contain a `BasicBlock` that *can* actually
-    /// unwind during execution. Otherwise, your dataflow results will not be correct.
-    pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet<BasicBlock>) -> Self {
-        self.dead_unwinds = Some(dead_unwinds);
-        self
+        Engine { analysis, tcx, body, pass_name: None, entry_sets, apply_trans_for_block }
     }
 
     /// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
@@ -190,14 +170,7 @@
         A::Domain: DebugWithContext<A>,
     {
         let Engine {
-            analysis,
-            body,
-            dead_unwinds,
-            mut entry_sets,
-            tcx,
-            apply_trans_for_block,
-            pass_name,
-            ..
+            analysis, body, mut entry_sets, tcx, apply_trans_for_block, pass_name, ..
         } = self;
 
         let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
@@ -236,7 +209,6 @@
                 &analysis,
                 tcx,
                 body,
-                dead_unwinds,
                 &mut state,
                 (bb, bb_data),
                 |target: BasicBlock, state: &A::Domain| {
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 6d30276..4a16302 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -126,7 +126,7 @@
                         BorrowedContent {
                             target_place: Place {
                                 local: place.local,
-                                projection: tcx.intern_place_elems(proj),
+                                projection: tcx.mk_place_elems(proj),
                             },
                         },
                     ));
@@ -165,7 +165,7 @@
             if union_path.is_none() {
                 base = self.add_move_path(base, elem, |tcx| Place {
                     local: place.local,
-                    projection: tcx.intern_place_elems(&place.projection[..i + 1]),
+                    projection: tcx.mk_place_elems(&place.projection[..i + 1]),
                 });
             }
         }
@@ -476,7 +476,7 @@
             // `ConstIndex` patterns. This is done to ensure that all move paths
             // are disjoint, which is expected by drop elaboration.
             let base_place =
-                Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) };
+                Place { local: place.local, projection: self.builder.tcx.mk_place_elems(base) };
             let base_path = match self.move_path_for(base_place) {
                 Ok(path) => path,
                 Err(MoveError::UnionMove { path }) => {
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index c57ec13..f27beb6 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -124,7 +124,7 @@
 
     fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
         if let Some(new_projection) = self.process_projection(&place.projection, loc) {
-            place.projection = self.tcx().intern_place_elems(&new_projection);
+            place.projection = self.tcx().mk_place_elems(&new_projection);
         }
 
         let observes_address = match ctxt {
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index dc58347..954bb5a 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -17,7 +17,7 @@
     unique_did: DefId,
     nonnull_did: DefId,
 ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
-    let substs = tcx.intern_substs(&[pointee.into()]);
+    let substs = tcx.mk_substs(&[pointee.into()]);
     let unique_ty = tcx.type_of(unique_did).subst(tcx, substs);
     let nonnull_ty = tcx.type_of(nonnull_did).subst(tcx, substs);
     let ptr_ty = tcx.mk_imm_ptr(pointee);
@@ -138,7 +138,7 @@
 
                     if let Some(mut new_projections) = new_projections {
                         new_projections.extend_from_slice(&place.projection[last_deref..]);
-                        place.projection = tcx.intern_place_elems(&new_projections);
+                        place.projection = tcx.mk_place_elems(&new_projections);
                     }
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index c2ff864..bdfd8dc 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -67,13 +67,11 @@
         };
         let un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: side_table };
         let elaborate_patch = {
-            let body = &*body;
             let env = MoveDataParamEnv { move_data, param_env };
-            let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer);
+            remove_dead_unwinds(tcx, body, &env, &un_derefer);
 
             let inits = MaybeInitializedPlaces::new(tcx, body, &env)
                 .into_engine(tcx, body)
-                .dead_unwinds(&dead_unwinds)
                 .pass_name("elaborate_drops")
                 .iterate_to_fixpoint()
                 .into_results_cursor(body);
@@ -81,11 +79,12 @@
             let uninits = MaybeUninitializedPlaces::new(tcx, body, &env)
                 .mark_inactive_variants_as_uninit()
                 .into_engine(tcx, body)
-                .dead_unwinds(&dead_unwinds)
                 .pass_name("elaborate_drops")
                 .iterate_to_fixpoint()
                 .into_results_cursor(body);
 
+            let reachable = traversal::reachable_as_bitset(body);
+
             ElaborateDropsCtxt {
                 tcx,
                 body,
@@ -94,6 +93,7 @@
                 drop_flags: Default::default(),
                 patch: MirPatch::new(body),
                 un_derefer: un_derefer,
+                reachable,
             }
             .elaborate()
         };
@@ -102,22 +102,21 @@
     }
 }
 
-/// Returns the set of basic blocks whose unwind edges are known
-/// to not be reachable, because they are `drop` terminators
+/// Removes unwind edges which are known to be unreachable, because they are in `drop` terminators
 /// that can't drop anything.
-fn find_dead_unwinds<'tcx>(
+fn remove_dead_unwinds<'tcx>(
     tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
+    body: &mut Body<'tcx>,
     env: &MoveDataParamEnv<'tcx>,
     und: &UnDerefer<'tcx>,
-) -> BitSet<BasicBlock> {
-    debug!("find_dead_unwinds({:?})", body.span);
+) {
+    debug!("remove_dead_unwinds({:?})", body.span);
     // We only need to do this pass once, because unwind edges can only
     // reach cleanup blocks, which can't have unwind edges themselves.
-    let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len());
+    let mut dead_unwinds = Vec::new();
     let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env)
         .into_engine(tcx, body)
-        .pass_name("find_dead_unwinds")
+        .pass_name("remove_dead_unwinds")
         .iterate_to_fixpoint()
         .into_results_cursor(body);
     for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
@@ -129,16 +128,16 @@
             _ => continue,
         };
 
-        debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data);
+        debug!("remove_dead_unwinds @ {:?}: {:?}", bb, bb_data);
 
         let LookupResult::Exact(path) = env.move_data.rev_lookup.find(place.as_ref()) else {
-            debug!("find_dead_unwinds: has parent; skipping");
+            debug!("remove_dead_unwinds: has parent; skipping");
             continue;
         };
 
         flow_inits.seek_before_primary_effect(body.terminator_loc(bb));
         debug!(
-            "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}",
+            "remove_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}",
             bb,
             place,
             path,
@@ -150,13 +149,22 @@
             maybe_live |= flow_inits.contains(child);
         });
 
-        debug!("find_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live);
+        debug!("remove_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live);
         if !maybe_live {
-            dead_unwinds.insert(bb);
+            dead_unwinds.push(bb);
         }
     }
 
-    dead_unwinds
+    if dead_unwinds.is_empty() {
+        return;
+    }
+
+    let basic_blocks = body.basic_blocks.as_mut();
+    for &bb in dead_unwinds.iter() {
+        if let Some(unwind) = basic_blocks[bb].terminator_mut().unwind_mut() {
+            *unwind = None;
+        }
+    }
 }
 
 struct InitializationData<'mir, 'tcx> {
@@ -290,6 +298,7 @@
     drop_flags: FxHashMap<MovePathIndex, Local>,
     patch: MirPatch<'tcx>,
     un_derefer: UnDerefer<'tcx>,
+    reachable: BitSet<BasicBlock>,
 }
 
 impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
@@ -329,6 +338,9 @@
 
     fn collect_drop_flags(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             let terminator = data.terminator();
             let place = match terminator.kind {
                 TerminatorKind::Drop { ref place, .. }
@@ -384,6 +396,9 @@
 
     fn elaborate_drops(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             let loc = Location { block: bb, statement_index: data.statements.len() };
             let terminator = data.terminator();
 
@@ -541,6 +556,9 @@
 
     fn drop_flags_for_fn_rets(&mut self) {
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             if let TerminatorKind::Call {
                 destination, target: Some(tgt), cleanup: Some(_), ..
             } = data.terminator().kind
@@ -576,6 +594,9 @@
         // clobbered before they are read.
 
         for (bb, data) in self.body.basic_blocks.iter_enumerated() {
+            if !self.reachable.contains(bb) {
+                continue;
+            }
             debug!("drop_flags_for_locs({:?})", data);
             for i in 0..(data.statements.len() + 1) {
                 debug!("drop_flag_for_locs: stmt {}", i);
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index dc5f88f..2e97312 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -126,7 +126,7 @@
                 place,
                 Place {
                     local: SELF_ARG,
-                    projection: self.tcx().intern_place_elems(&[ProjectionElem::Deref]),
+                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
                 },
                 self.tcx,
             );
@@ -162,10 +162,9 @@
                 place,
                 Place {
                     local: SELF_ARG,
-                    projection: self.tcx().intern_place_elems(&[ProjectionElem::Field(
-                        Field::new(0),
-                        self.ref_gen_ty,
-                    )]),
+                    projection: self
+                        .tcx()
+                        .mk_place_elems(&[ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
                 },
                 self.tcx,
             );
@@ -187,7 +186,7 @@
     let mut new_projection = new_base.projection.to_vec();
     new_projection.append(&mut place.projection.to_vec());
 
-    place.projection = tcx.intern_place_elems(&new_projection);
+    place.projection = tcx.mk_place_elems(&new_projection);
 }
 
 const SELF_ARG: Local = Local::from_u32(1);
@@ -300,7 +299,7 @@
         let mut projection = base.projection.to_vec();
         projection.push(ProjectionElem::Field(Field::new(idx), ty));
 
-        Place { local: base.local, projection: self.tcx.intern_place_elems(&projection) }
+        Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) }
     }
 
     // Create a statement which changes the discriminant
@@ -427,7 +426,7 @@
 
     let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span));
     let pin_adt_ref = tcx.adt_def(pin_did);
-    let substs = tcx.intern_substs(&[ref_gen_ty.into()]);
+    let substs = tcx.mk_substs(&[ref_gen_ty.into()]);
     let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs);
 
     // Replace the by ref generator argument
@@ -1450,13 +1449,13 @@
             // Compute Poll<return_ty>
             let poll_did = tcx.require_lang_item(LangItem::Poll, None);
             let poll_adt_ref = tcx.adt_def(poll_did);
-            let poll_substs = tcx.intern_substs(&[body.return_ty().into()]);
+            let poll_substs = tcx.mk_substs(&[body.return_ty().into()]);
             (poll_adt_ref, poll_substs)
         } else {
             // Compute GeneratorState<yield_ty, return_ty>
             let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
             let state_adt_ref = tcx.adt_def(state_did);
-            let state_substs = tcx.intern_substs(&[yield_ty.into(), body.return_ty().into()]);
+            let state_substs = tcx.mk_substs(&[yield_ty.into(), body.return_ty().into()]);
             (state_adt_ref, state_substs)
         };
         let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 8c6b046..6e6d656 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -888,7 +888,7 @@
         location: Location,
     ) {
         if let ProjectionElem::Field(f, ty) = elem {
-            let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+            let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) };
             let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx);
             let check_equal = |this: &mut Self, f_ty| {
                 if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) {
diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs
index 3896f0e..14e644b 100644
--- a/compiler/rustc_mir_transform/src/instcombine.rs
+++ b/compiler/rustc_mir_transform/src/instcombine.rs
@@ -121,7 +121,7 @@
 
                 *rvalue = Rvalue::Use(Operand::Copy(Place {
                     local: base.local,
-                    projection: self.tcx.intern_place_elems(base.projection),
+                    projection: self.tcx.mk_place_elems(base.projection),
                 }));
             }
         }
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
index 2ca33a6..89e0a00 100644
--- a/compiler/rustc_mir_transform/src/large_enums.rs
+++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -114,7 +114,7 @@
             tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi,
             Mutability::Not,
         );
-        let alloc = tcx.create_memory_alloc(tcx.intern_const_alloc(alloc));
+        let alloc = tcx.create_memory_alloc(tcx.mk_const_alloc(alloc));
         Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc)))
     }
     fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -197,9 +197,8 @@
                             size_place,
                             Rvalue::Use(Operand::Copy(Place {
                                 local: size_array_local,
-                                projection: tcx.intern_place_elems(&[PlaceElem::Index(
-                                    discr_cast_place.local,
-                                )]),
+                                projection: tcx
+                                    .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]),
                             })),
                         )),
                     };
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index bdd1e8f..4193eb7 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -192,7 +192,7 @@
                 let arguments = (0..num_args).map(|x| {
                     let mut place_elems = place_elems.to_vec();
                     place_elems.push(ProjectionElem::Field(x.into(), fields[x]));
-                    let projection = tcx.intern_place_elems(&place_elems);
+                    let projection = tcx.mk_place_elems(&place_elems);
                     let place = Place {
                         local: place.local,
                         projection,
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 682ad08..ebe63d6 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -147,7 +147,7 @@
     assert!(!matches!(ty, Some(ty) if ty.is_generator()));
 
     let substs = if let Some(ty) = ty {
-        tcx.intern_substs(&[ty.into()])
+        tcx.mk_substs(&[ty.into()])
     } else {
         InternalSubsts::identity_for_item(tcx, def_id)
     };
@@ -597,7 +597,7 @@
         let untuple_args = sig.inputs();
 
         // Create substitutions for the `Self` and `Args` generic parameters of the shim body.
-        let arg_tup = tcx.intern_tup(untuple_args);
+        let arg_tup = tcx.mk_tup(untuple_args);
 
         (Some([ty.into(), arg_tup.into()]), Some(untuple_args))
     } else {
@@ -632,7 +632,7 @@
             Adjustment::Deref => tcx.mk_imm_ptr(fnty),
             Adjustment::RefMut => tcx.mk_mut_ptr(fnty),
         };
-        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+        sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
     }
 
     // FIXME(eddyb) avoid having this snippet both here and in
@@ -643,7 +643,7 @@
         let self_arg = &mut inputs_and_output[0];
         debug_assert!(tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param);
         *self_arg = tcx.mk_mut_ptr(*self_arg);
-        sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+        sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
     }
 
     let span = tcx.def_span(def_id);
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 8a37423..13168e9 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -122,7 +122,7 @@
         let &[PlaceElem::Field(f, _), ref rest @ ..] = place.projection else { return None; };
         let fields = self.fragments[place.local].as_ref()?;
         let (_, new_local) = fields[f]?;
-        Some(Place { local: new_local, projection: tcx.intern_place_elems(&rest) })
+        Some(Place { local: new_local, projection: tcx.mk_place_elems(&rest) })
     }
 
     fn place_fragments(
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index ff409a8..45e659e 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1298,7 +1298,7 @@
             self.tcx,
             ty::ParamEnv::reveal_all(),
             start_def_id,
-            self.tcx.intern_substs(&[main_ret_ty.into()]),
+            self.tcx.mk_substs(&[main_ret_ty.into()]),
         )
         .unwrap()
         .unwrap();
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 623c82b..fda9151 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -982,7 +982,11 @@
         let initial_semicolon = self.token.span;
 
         while self.eat(&TokenKind::Semi) {
-            let _ = self.parse_stmt(ForceCollect::Yes)?;
+            let _ =
+                self.parse_stmt_without_recovery(false, ForceCollect::Yes).unwrap_or_else(|e| {
+                    e.cancel();
+                    None
+                });
         }
 
         expect_err.set_primary_message(
diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/locales/en-US.ftl
index 0c7e029..8fe8472 100644
--- a/compiler/rustc_passes/locales/en-US.ftl
+++ b/compiler/rustc_passes/locales/en-US.ftl
@@ -407,10 +407,10 @@
 
 passes_duplicate_diagnostic_item_in_crate =
     duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
+    .note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
 
 passes_diagnostic_item_first_defined =
     the diagnostic item is first defined here
-    .note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
 
 passes_abi =
     abi: {$abi}
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 88a55dc..16194a6 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -748,7 +748,10 @@
                         let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
                         c.visit_ty(self_ty);
                         c.visit_trait_ref(t);
-                        if c.fully_stable {
+
+                        // do not lint when the trait isn't resolved, since resolution error should
+                        // be fixed first
+                        if t.path.res != Res::Err && c.fully_stable {
                             self.tcx.struct_span_lint_hir(
                                 INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
                                 item.hir_id(),
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 9443ded..35fa932 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -6,6 +6,7 @@
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
+use rustc_data_structures::OnDrop;
 use rustc_index::vec::IndexVec;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use smallvec::{smallvec, SmallVec};
@@ -671,17 +672,24 @@
         let prev_index = data.previous.node_to_index_opt(dep_node)?;
 
         match data.colors.get(prev_index) {
-            Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
-            Some(DepNodeColor::Red) => None,
-            None => {
-                // This DepNode and the corresponding query invocation existed
-                // in the previous compilation session too, so we can try to
-                // mark it as green by recursively marking all of its
-                // dependencies green.
-                self.try_mark_previous_green(qcx, data, prev_index, &dep_node)
-                    .map(|dep_node_index| (prev_index, dep_node_index))
-            }
+            Some(DepNodeColor::Green(dep_node_index)) => return Some((prev_index, dep_node_index)),
+            Some(DepNodeColor::Red) => return None,
+            None => {}
         }
+
+        let backtrace = backtrace_printer(qcx.dep_context().sess(), data, prev_index);
+
+        // This DepNode and the corresponding query invocation existed
+        // in the previous compilation session too, so we can try to
+        // mark it as green by recursively marking all of its
+        // dependencies green.
+        let ret = self
+            .try_mark_previous_green(qcx, data, prev_index, &dep_node)
+            .map(|dep_node_index| (prev_index, dep_node_index));
+
+        // We succeeded, no backtrace.
+        backtrace.disable();
+        return ret;
     }
 
     #[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")]
@@ -794,7 +802,10 @@
         let prev_deps = data.previous.edge_targets_from(prev_dep_node_index);
 
         for &dep_dep_node_index in prev_deps {
-            self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node)?
+            let backtrace = backtrace_printer(qcx.dep_context().sess(), data, dep_dep_node_index);
+            let success = self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node);
+            backtrace.disable();
+            success?;
         }
 
         // If we got here without hitting a `return` that means that all
@@ -1364,3 +1375,26 @@
         )
     }
 }
+
+fn backtrace_printer<'a, K: DepKind>(
+    sess: &'a rustc_session::Session,
+    graph: &'a DepGraphData<K>,
+    node: SerializedDepNodeIndex,
+) -> OnDrop<impl Fn() + 'a> {
+    OnDrop(
+        #[inline(never)]
+        #[cold]
+        move || {
+            let node = graph.previous.index_to_node(node);
+            // Do not try to rely on DepNode's Debug implementation, since it may panic.
+            let diag = rustc_errors::Diagnostic::new(
+                rustc_errors::Level::FailureNote,
+                &format!(
+                    "encountered while trying to mark dependency green: {:?}({})",
+                    node.kind, node.hash
+                ),
+            );
+            sess.diagnostic().force_print_diagnostic(diag);
+        },
+    )
+}
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index e840108..4b3cd16 100644
--- a/compiler/rustc_query_system/src/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -21,7 +21,7 @@
 }
 
 pub trait QueryCache: QueryStorage + Sized {
-    type Key: Hash + Eq + Clone + Debug;
+    type Key: Hash + Eq + Copy + Debug;
 
     /// Checks if the query is already computed and in the cache.
     /// It returns the shard index and a lock guard to the shard,
@@ -61,7 +61,7 @@
 
 impl<K, V> QueryCache for DefaultCache<K, V>
 where
-    K: Eq + Hash + Clone + Debug,
+    K: Eq + Hash + Copy + Debug,
     V: Copy + Debug,
 {
     type Key = K;
@@ -179,7 +179,7 @@
 
 impl<K, V> QueryCache for VecCache<K, V>
 where
-    K: Eq + Idx + Clone + Debug,
+    K: Eq + Idx + Copy + Debug,
     V: Copy + Debug,
 {
     type Key = K;
diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs
index 56247e8..d563738 100644
--- a/compiler/rustc_query_system/src/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
@@ -19,7 +19,9 @@
 pub trait QueryConfig<Qcx: QueryContext> {
     const NAME: &'static str;
 
-    type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Clone + Debug;
+    // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap,
+    // but it isn't necessary.
+    type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Copy + Debug;
     type Value: Debug + Copy;
 
     type Cache: QueryCache<Key = Self::Key, Value = Self::Value>;
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 21a0c73..5499165 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -48,7 +48,7 @@
 
 impl<K, D> QueryState<K, D>
 where
-    K: Eq + Hash + Clone + Debug,
+    K: Eq + Hash + Copy + Debug,
     D: DepKind,
 {
     pub fn all_inactive(&self) -> bool {
@@ -77,7 +77,7 @@
             for shard in shards.iter() {
                 for (k, v) in shard.iter() {
                     if let QueryResult::Started(ref job) = *v {
-                        let query = make_query(qcx, k.clone());
+                        let query = make_query(qcx, *k);
                         jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
                     }
                 }
@@ -91,7 +91,7 @@
             // really hurt much.)
             for (k, v) in self.active.try_lock()?.iter() {
                 if let QueryResult::Started(ref job) = *v {
-                    let query = make_query(qcx, k.clone());
+                    let query = make_query(qcx, *k);
                     jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
                 }
             }
@@ -111,7 +111,7 @@
 /// This will poison the relevant query if dropped.
 struct JobOwner<'tcx, K, D: DepKind>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
 {
     state: &'tcx QueryState<K, D>,
     key: K,
@@ -163,7 +163,7 @@
 
 impl<'tcx, K, D: DepKind> JobOwner<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
 {
     /// Either gets a `JobOwner` corresponding the query, allowing us to
     /// start executing the query, or returns with the result of the query.
@@ -195,7 +195,7 @@
                 let job = qcx.current_query_job();
                 let job = QueryJob::new(id, span, job);
 
-                let key = entry.key().clone();
+                let key = *entry.key();
                 entry.insert(QueryResult::Started(job));
 
                 let owner = JobOwner { state, id, key };
@@ -274,7 +274,7 @@
 
 impl<'tcx, K, D> Drop for JobOwner<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
     D: DepKind,
 {
     #[inline(never)]
@@ -291,7 +291,7 @@
                 QueryResult::Started(job) => job,
                 QueryResult::Poisoned => panic!(),
             };
-            shard.insert(self.key.clone(), QueryResult::Poisoned);
+            shard.insert(self.key, QueryResult::Poisoned);
             job
         };
         // Also signal the completion of the job, so waiters
@@ -310,7 +310,7 @@
 /// The result of `try_start`.
 enum TryGetJob<'tcx, K, D>
 where
-    K: Eq + Hash + Clone,
+    K: Eq + Hash + Copy,
     D: DepKind,
 {
     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
@@ -358,10 +358,9 @@
     Q: QueryConfig<Qcx>,
     Qcx: QueryContext,
 {
-    match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key.clone()) {
+    match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key) {
         TryGetJob::NotYetStarted(job) => {
-            let (result, dep_node_index) =
-                execute_job::<Q, Qcx>(qcx, key.clone(), dep_node, job.id);
+            let (result, dep_node_index) = execute_job::<Q, Qcx>(qcx, key, dep_node, job.id);
             if Q::FEEDABLE {
                 // We should not compute queries that also got a value via feeding.
                 // This can't happen, as query feeding adds the very dependencies to the fed query
@@ -551,7 +550,7 @@
     let prof_timer = qcx.dep_context().profiler().query_provider();
 
     // The dep-graph for this computation is already in-place.
-    let result = dep_graph.with_ignore(|| Q::compute(qcx, key.clone()));
+    let result = dep_graph.with_ignore(|| Q::compute(qcx, *key));
 
     prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 1d299e2..1a679f3 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -675,7 +675,7 @@
         _ if ty.is_unit() => {}
 
         ty::Tuple(tys) => {
-            ty = tcx.mk_tup(tys.iter().map(|ty| transform_ty(tcx, ty, options)));
+            ty = tcx.mk_tup_from_iter(tys.iter().map(|ty| transform_ty(tcx, ty, options)));
         }
 
         ty::Array(ty0, len) => {
@@ -825,7 +825,7 @@
             subst
         }
     });
-    tcx.mk_substs(substs)
+    tcx.mk_substs_from_iter(substs)
 }
 
 /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index c080f7e..71f536d 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -567,7 +567,7 @@
 ) -> Result<ExternalConstraints<'tcx>, NoSolution> {
     let region_obligations = infcx.take_registered_region_obligations();
     let opaque_types = infcx.take_opaque_types_for_query_response();
-    Ok(infcx.tcx.intern_external_constraints(ExternalConstraintsData {
+    Ok(infcx.tcx.mk_external_constraints(ExternalConstraintsData {
         // FIXME: Now that's definitely wrong :)
         //
         // Should also do the leak check here I think
@@ -616,8 +616,7 @@
             var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
             // FIXME: maybe we should store the "no response" version in tcx, like
             // we do for tcx.types and stuff.
-            external_constraints: tcx
-                .intern_external_constraints(ExternalConstraintsData::default()),
+            external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
             certainty,
         },
     })
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index aff7973..68bb7c8 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -343,9 +343,10 @@
                     // Substitute just the unsizing params from B into A. The type after
                     // this substitution must be equal to B. This is so we don't unsize
                     // unrelated type parameters.
-                    let new_a_substs = tcx.mk_substs(a_substs.iter().enumerate().map(|(i, a)| {
-                        if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
-                    }));
+                    let new_a_substs =
+                        tcx.mk_substs_from_iter(a_substs.iter().enumerate().map(|(i, a)| {
+                            if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
+                        }));
                     let unsized_a_ty = tcx.mk_adt(a_def, new_a_substs);
 
                     // Finally, we require that `TailA: Unsize<TailB>` for the tail field
@@ -368,7 +369,8 @@
                     let b_last_ty = b_tys.last().unwrap();
 
                     // Substitute just the tail field of B., and require that they're equal.
-                    let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied());
+                    let unsized_a_ty =
+                        tcx.mk_tup_from_iter(a_rest_tys.iter().chain([b_last_ty]).copied());
                     let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?;
 
                     // Similar to ADTs, require that the rest of the fields are equal.
@@ -425,7 +427,7 @@
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let new_a_data = tcx.mk_poly_existential_predicates(new_a_data);
+                let new_a_data = tcx.mk_poly_existential_predicates_from_iter(new_a_data);
                 let new_a_ty = tcx.mk_dynamic(new_a_data, b_region, ty::Dyn);
 
                 // We also require that A's lifetime outlives B's lifetime.
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
index 2c13465..3a887f5 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
@@ -189,11 +189,9 @@
         ty::FnDef(def_id, substs) => Ok(Some(
             tcx.fn_sig(def_id)
                 .subst(tcx, substs)
-                .map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())),
+                .map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())),
         )),
-        ty::FnPtr(sig) => {
-            Ok(Some(sig.map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output()))))
-        }
+        ty::FnPtr(sig) => Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))),
         ty::Closure(_, substs) => {
             let closure_substs = substs.as_closure();
             match closure_substs.kind_ty().to_opt_closure_kind() {
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6f2b085..1fb8659 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -350,14 +350,14 @@
             )
             .map(|o| o.predicate);
             new_env = ty::ParamEnv::new(
-                tcx.mk_predicates(normalized_preds),
+                tcx.mk_predicates_from_iter(normalized_preds),
                 param_env.reveal(),
                 param_env.constness(),
             );
         }
 
         let final_user_env = ty::ParamEnv::new(
-            tcx.mk_predicates(user_computed_preds.into_iter()),
+            tcx.mk_predicates_from_iter(user_computed_preds.into_iter()),
             user_env.reveal(),
             user_env.constness(),
         );
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index c8b233b..b2317f5 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -281,7 +281,7 @@
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
     let elaborated_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
+        tcx.mk_predicates(&predicates),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     );
@@ -333,10 +333,9 @@
     // Not sure whether it is better to include the unnormalized TypeOutlives predicates
     // here. I believe they should not matter, because we are ignoring TypeOutlives param-env
     // predicates here anyway. Keeping them here anyway because it seems safer.
-    let outlives_env: Vec<_> =
-        non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
+    let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
     let outlives_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&outlives_env),
+        tcx.mk_predicates_from_iter(outlives_env),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     );
@@ -356,7 +355,7 @@
     predicates.extend(outlives_predicates);
     debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
     ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
+        tcx.mk_predicates(&predicates),
         unnormalized_env.reveal(),
         unnormalized_env.constness(),
     )
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index b87f754..4eacb52 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -18,10 +18,10 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{
     self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
-use rustc_middle::ty::{Predicate, ToPredicate};
 use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
@@ -666,8 +666,9 @@
     elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
     elaborated_predicates.dedup();
 
-    let existential_predicates = tcx
-        .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates));
+    let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(
+        iter::once(trait_predicate).chain(elaborated_predicates),
+    );
     debug!(?existential_predicates);
 
     tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn)
@@ -766,11 +767,11 @@
             ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, substs)).to_predicate(tcx)
         };
 
-        let caller_bounds: Vec<Predicate<'tcx>> =
-            param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]).collect();
+        let caller_bounds =
+            param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
 
         ty::ParamEnv::new(
-            tcx.intern_predicates(&caller_bounds),
+            tcx.mk_predicates_from_iter(caller_bounds),
             param_env.reveal(),
             param_env.constness(),
         )
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 14bba00..e5b0f9d 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1906,7 +1906,7 @@
 ) -> Progress<'tcx> {
     let tcx = selcx.tcx();
     let self_ty = obligation.predicate.self_ty();
-    let substs = tcx.intern_substs(&[self_ty.into()]);
+    let substs = tcx.mk_substs(&[self_ty.into()]);
     let lang_items = tcx.lang_items();
     let item_def_id = obligation.predicate.def_id;
     let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 270f513..21c158f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -564,8 +564,8 @@
                                 .into()
                             }
                         });
-                        let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars);
-                        let assoc_ty_substs = tcx.intern_substs(&substs);
+                        let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
+                        let assoc_ty_substs = tcx.mk_substs(&substs);
                         let bound =
                             bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
                         tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
@@ -880,7 +880,7 @@
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+                let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
 
                 // Require that the traits involved in this upcast are **equal**;
@@ -979,7 +979,7 @@
                             .map(ty::ExistentialPredicate::AutoTrait)
                             .map(ty::Binder::dummy),
                     );
-                let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+                let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
 
                 // Require that the traits involved in this upcast are **equal**;
@@ -1099,7 +1099,7 @@
 
                 // Check that the source struct with the target's
                 // unsizing parameters is equal to the target.
-                let substs = tcx.mk_substs(substs_a.iter().enumerate().map(|(i, k)| {
+                let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| {
                     if unsizing_params.contains(i as u32) { substs_b[i] } else { k }
                 }));
                 let new_struct = tcx.mk_adt(def, substs);
@@ -1131,7 +1131,8 @@
 
                 // Check that the source tuple with the target's
                 // last element is equal to the target.
-                let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last)));
+                let new_tuple =
+                    tcx.mk_tup_from_iter(a_mid.iter().copied().chain(iter::once(b_last)));
                 let InferOk { obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index e2fb954..a2c16e6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2230,7 +2230,7 @@
                     }
                 }
                 // (*) binder moved here
-                let all_vars = self.tcx().mk_bound_variable_kinds(
+                let all_vars = self.tcx().mk_bound_variable_kinds_from_iter(
                     obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
                 );
                 Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
@@ -3034,7 +3034,7 @@
     if considering_regions {
         debug_assert!(!hidden_types.has_erased_regions());
     }
-    let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.iter().chain(
+    let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
         (num_bound_variables..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))),
     ));
     ty::Binder::bind_with_vars(hidden_types, bound_vars)
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 638a659..bcf63d5 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -292,7 +292,7 @@
     assert!(!self_ty.has_escaping_bound_vars());
     let arguments_tuple = match tuple_arguments {
         TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
-        TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
+        TupleArgumentsFlag::Yes => tcx.mk_tup(sig.skip_binder().inputs()),
     };
     let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
     sig.map_bound(|sig| (trait_ref, sig.output()))
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 50cd1d1..60e22d1 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -62,7 +62,9 @@
 
 impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> {
     fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> {
-        interner.tcx.mk_substs(self.iter(interner).map(|subst| subst.lower_into(interner)))
+        interner
+            .tcx
+            .mk_substs_from_iter(self.iter(interner).map(|subst| subst.lower_into(interner)))
     }
 }
 
@@ -487,7 +489,7 @@
             TyKind::InferenceVar(_, _) => unimplemented!(),
             TyKind::Dyn(_) => unimplemented!(),
         };
-        interner.tcx.mk_ty(kind)
+        interner.tcx.mk_ty_from_kind(kind)
     }
 }
 
diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs
index 5855a8e..a5ebc26 100644
--- a/compiler/rustc_traits/src/chalk/mod.rs
+++ b/compiler/rustc_traits/src/chalk/mod.rs
@@ -96,37 +96,34 @@
         use rustc_middle::infer::canonical::CanonicalVarInfo;
 
         let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
-        let var_values = tcx.mk_substs(
+        let var_values = tcx.mk_substs_from_iter(
             subst
                 .as_slice(interner)
                 .iter()
                 .map(|p| p.lower_into(interner).fold_with(&mut reverse_param_substitutor)),
         );
-        let variables: Vec<_> = binders
-            .iter(interner)
-            .map(|var| {
-                let kind = match var.kind {
-                    chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
-                        chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
-                            ty::UniverseIndex::from_usize(var.skip_kind().counter),
-                        ),
-                        chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
-                        chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
-                    }),
-                    chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region(
+        let variables = binders.iter(interner).map(|var| {
+            let kind = match var.kind {
+                chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind {
+                    chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General(
                         ty::UniverseIndex::from_usize(var.skip_kind().counter),
                     ),
-                    // FIXME(compiler-errors): We don't currently have a way of turning
-                    // a Chalk ty back into a rustc ty, right?
-                    chalk_ir::VariableKind::Const(_) => todo!(),
-                };
-                CanonicalVarInfo { kind }
-            })
-            .collect();
+                    chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int,
+                    chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float,
+                }),
+                chalk_ir::VariableKind::Lifetime => {
+                    CanonicalVarKind::Region(ty::UniverseIndex::from_usize(var.skip_kind().counter))
+                }
+                // FIXME(compiler-errors): We don't currently have a way of turning
+                // a Chalk ty back into a rustc ty, right?
+                chalk_ir::VariableKind::Const(_) => todo!(),
+            };
+            CanonicalVarInfo { kind }
+        });
         let max_universe = binders.iter(interner).map(|v| v.skip_kind().counter).max().unwrap_or(0);
         let sol = Canonical {
             max_universe: ty::UniverseIndex::from_usize(max_universe),
-            variables: tcx.intern_canonical_var_infos(&variables),
+            variables: tcx.mk_canonical_var_infos_from_iter(variables),
             value: QueryResponse {
                 var_values: CanonicalVarValues { var_values },
                 region_constraints: QueryRegionConstraints::default(),
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 41924dc..35c9f95 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -54,7 +54,7 @@
                 sig = sig.map_bound(|mut sig| {
                     let mut inputs_and_output = sig.inputs_and_output.to_vec();
                     inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]);
-                    sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output);
+                    sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
                     sig
                 });
             }
@@ -63,7 +63,7 @@
         ty::Closure(def_id, substs) => {
             let sig = substs.as_closure().sig();
 
-            let bound_vars = tcx.mk_bound_variable_kinds(
+            let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                 sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
             );
             let br = ty::BoundRegion {
@@ -88,7 +88,7 @@
         ty::Generator(did, substs, _) => {
             let sig = substs.as_generator().poly_sig();
 
-            let bound_vars = tcx.mk_bound_variable_kinds(
+            let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
                 sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
             );
             let br = ty::BoundRegion {
@@ -99,7 +99,7 @@
 
             let pin_did = tcx.require_lang_item(LangItem::Pin, None);
             let pin_adt_ref = tcx.adt_def(pin_did);
-            let pin_substs = tcx.intern_substs(&[env_ty.into()]);
+            let pin_substs = tcx.mk_substs(&[env_ty.into()]);
             let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
 
             let sig = sig.skip_binder();
@@ -111,7 +111,7 @@
                 // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
                 let poll_did = tcx.require_lang_item(LangItem::Poll, None);
                 let poll_adt_ref = tcx.adt_def(poll_did);
-                let poll_substs = tcx.intern_substs(&[sig.return_ty.into()]);
+                let poll_substs = tcx.mk_substs(&[sig.return_ty.into()]);
                 let ret_ty = tcx.mk_adt(poll_adt_ref, poll_substs);
 
                 // We have to replace the `ResumeTy` that is used for type and borrow checking
@@ -133,7 +133,7 @@
                 // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>`
                 let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
                 let state_adt_ref = tcx.adt_def(state_did);
-                let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
+                let state_substs = tcx.mk_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
                 let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
 
                 (sig.resume_ty, ret_ty)
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index ae824a3..f263527 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -144,7 +144,7 @@
             for &id in args.iter() {
                 new_args.push(recurse_build(tcx, body, id, root_span)?);
             }
-            let new_args = tcx.intern_const_list(&new_args);
+            let new_args = tcx.mk_const_list(&new_args);
             tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty)
         }
         &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index eb307e6..7fecee2 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -19,16 +19,16 @@
             let mut assumed_wf_types: Vec<_> =
                 tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
             assumed_wf_types.extend(liberated_sig.inputs_and_output);
-            tcx.intern_type_list(&assumed_wf_types)
+            tcx.mk_type_list(&assumed_wf_types)
         }
         DefKind::Impl { .. } => {
             match tcx.impl_trait_ref(def_id) {
                 Some(trait_ref) => {
                     let types: Vec<_> = trait_ref.skip_binder().substs.types().collect();
-                    tcx.intern_type_list(&types)
+                    tcx.mk_type_list(&types)
                 }
                 // Only the impl self type
-                None => tcx.intern_type_list(&[tcx.type_of(def_id).subst_identity()]),
+                None => tcx.mk_type_list(&[tcx.type_of(def_id).subst_identity()]),
             }
         }
         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index a400fbf..e3132fc 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -104,23 +104,23 @@
         assert!(size.bits() <= 128);
         Scalar::Initialized { value, valid_range: WrappingRange::full(size) }
     };
-    let scalar = |value: Primitive| tcx.intern_layout(LayoutS::scalar(cx, scalar_unit(value)));
+    let scalar = |value: Primitive| tcx.mk_layout(LayoutS::scalar(cx, scalar_unit(value)));
 
     let univariant = |fields: &[Layout<'_>], repr: &ReprOptions, kind| {
-        Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
+        Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
     };
     debug_assert!(!ty.has_non_region_infer());
 
     Ok(match *ty.kind() {
         // Basic scalars.
-        ty::Bool => tcx.intern_layout(LayoutS::scalar(
+        ty::Bool => tcx.mk_layout(LayoutS::scalar(
             cx,
             Scalar::Initialized {
                 value: Int(I8, false),
                 valid_range: WrappingRange { start: 0, end: 1 },
             },
         )),
-        ty::Char => tcx.intern_layout(LayoutS::scalar(
+        ty::Char => tcx.mk_layout(LayoutS::scalar(
             cx,
             Scalar::Initialized {
                 value: Int(I32, false),
@@ -136,11 +136,11 @@
         ty::FnPtr(_) => {
             let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
             ptr.valid_range_mut().start = 1;
-            tcx.intern_layout(LayoutS::scalar(cx, ptr))
+            tcx.mk_layout(LayoutS::scalar(cx, ptr))
         }
 
         // The never type.
-        ty::Never => tcx.intern_layout(cx.layout_of_never_type()),
+        ty::Never => tcx.mk_layout(cx.layout_of_never_type()),
 
         // Potentially-wide pointers.
         ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
@@ -151,7 +151,7 @@
 
             let pointee = tcx.normalize_erasing_regions(param_env, pointee);
             if pointee.is_sized(tcx, param_env) {
-                return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
             }
 
             let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
@@ -164,7 +164,7 @@
                 let metadata_layout = cx.layout_of(metadata_ty)?;
                 // If the metadata is a 1-zst, then the pointer is thin.
                 if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 {
-                    return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                    return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
                 }
 
                 let Abi::Scalar(metadata) = metadata_layout.abi else {
@@ -174,7 +174,7 @@
             } else {
                 match unsized_part.kind() {
                     ty::Foreign(..) => {
-                        return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+                        return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
                     }
                     ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
                     ty::Dynamic(..) => {
@@ -189,7 +189,7 @@
             };
 
             // Effectively a (ptr, meta) tuple.
-            tcx.intern_layout(cx.scalar_pair(data_ptr, metadata))
+            tcx.mk_layout(cx.scalar_pair(data_ptr, metadata))
         }
 
         ty::Dynamic(_, _, ty::DynStar) => {
@@ -197,7 +197,7 @@
             data.valid_range_mut().start = 0;
             let mut vtable = scalar_unit(Pointer(AddressSpace::DATA));
             vtable.valid_range_mut().start = 1;
-            tcx.intern_layout(cx.scalar_pair(data, vtable))
+            tcx.mk_layout(cx.scalar_pair(data, vtable))
         }
 
         // Arrays and slices.
@@ -222,7 +222,7 @@
 
             let largest_niche = if count != 0 { element.largest_niche } else { None };
 
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields: FieldsShape::Array { stride: element.size, count },
                 abi,
@@ -233,7 +233,7 @@
         }
         ty::Slice(element) => {
             let element = cx.layout_of(element)?;
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
                 abi: Abi::Aggregate { sized: false },
@@ -242,7 +242,7 @@
                 size: Size::ZERO,
             })
         }
-        ty::Str => tcx.intern_layout(LayoutS {
+        ty::Str => tcx.mk_layout(LayoutS {
             variants: Variants::Single { index: VariantIdx::new(0) },
             fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
             abi: Abi::Aggregate { sized: false },
@@ -265,7 +265,7 @@
                 Abi::Aggregate { ref mut sized } => *sized = false,
                 _ => bug!(),
             }
-            tcx.intern_layout(unit)
+            tcx.mk_layout(unit)
         }
 
         ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?,
@@ -394,7 +394,7 @@
                 FieldsShape::Array { stride: e_ly.size, count: e_len }
             };
 
-            tcx.intern_layout(LayoutS {
+            tcx.mk_layout(LayoutS {
                 variants: Variants::Single { index: VariantIdx::new(0) },
                 fields,
                 abi: Abi::Vector { element: e_abi, count: e_len },
@@ -427,12 +427,12 @@
                     return Err(LayoutError::Unknown(ty));
                 }
 
-                return Ok(tcx.intern_layout(
+                return Ok(tcx.mk_layout(
                     cx.layout_of_union(&def.repr(), &variants).ok_or(LayoutError::Unknown(ty))?,
                 ));
             }
 
-            tcx.intern_layout(
+            tcx.mk_layout(
                 cx.layout_of_struct_or_enum(
                     &def.repr(),
                     &variants,
@@ -636,7 +636,7 @@
         value: Primitive::Int(discr_int, false),
         valid_range: WrappingRange { start: 0, end: max_discr },
     };
-    let tag_layout = cx.tcx.intern_layout(LayoutS::scalar(cx, tag));
+    let tag_layout = cx.tcx.mk_layout(LayoutS::scalar(cx, tag));
 
     let promoted_layouts = ineligible_locals
         .iter()
@@ -784,7 +784,7 @@
         Abi::Aggregate { sized: true }
     };
 
-    let layout = tcx.intern_layout(LayoutS {
+    let layout = tcx.mk_layout(LayoutS {
         variants: Variants::Multiple {
             tag,
             tag_encoding: TagEncoding::Direct,
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index c177d60..de7fd00 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -303,7 +303,7 @@
         false,
     )
     .collect::<Result<Vec<_>, _>>()
-    .map(|components| tcx.intern_type_list(&components))
+    .map(|components| tcx.mk_type_list(&components))
 }
 // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed
 // a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitute the generic parameters
@@ -320,7 +320,7 @@
         true,
     )
     .collect::<Result<Vec<_>, _>>()
-    .map(|components| tcx.intern_type_list(&components))
+    .map(|components| tcx.mk_type_list(&components))
 }
 
 pub(crate) fn provide(providers: &mut ty::query::Providers) {
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 853c50f..1815977 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -98,12 +98,12 @@
 fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
     if let Some(def_id) = def_id.as_local() {
         if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
-            return tcx.intern_type_list(&[tcx.ty_error_misc()]);
+            return tcx.mk_type_list(&[tcx.ty_error_misc()]);
         }
     }
     let def = tcx.adt_def(def_id);
 
-    let result = tcx.mk_type_list(
+    let result = tcx.mk_type_list_from_iter(
         def.variants()
             .iter()
             .flat_map(|v| v.fields.last())
@@ -226,11 +226,8 @@
         None => hir::Constness::NotConst,
     };
 
-    let unnormalized_env = ty::ParamEnv::new(
-        tcx.intern_predicates(&predicates),
-        traits::Reveal::UserFacing,
-        constness,
-    );
+    let unnormalized_env =
+        ty::ParamEnv::new(tcx.mk_predicates(&predicates), traits::Reveal::UserFacing, constness);
 
     let body_id = local_did.unwrap_or(CRATE_DEF_ID);
     let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
@@ -386,7 +383,7 @@
         }
     });
 
-    tcx.mk_predicates(clauses.chain(input_clauses))
+    tcx.mk_predicates_from_iter(clauses.chain(input_clauses))
 }
 
 fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 0b73b1a..f1d0a30 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -851,18 +851,30 @@
     where
         F: FnMut(&T) -> bool,
     {
-        let mut first_removed = self.len();
+        struct RebuildOnDrop<'a, T: Ord> {
+            heap: &'a mut BinaryHeap<T>,
+            first_removed: usize,
+        }
+
+        let mut guard = RebuildOnDrop { first_removed: self.len(), heap: self };
+
         let mut i = 0;
-        self.data.retain(|e| {
+        guard.heap.data.retain(|e| {
             let keep = f(e);
-            if !keep && i < first_removed {
-                first_removed = i;
+            if !keep && i < guard.first_removed {
+                guard.first_removed = i;
             }
             i += 1;
             keep
         });
-        // data[0..first_removed] is untouched, so we only need to rebuild the tail:
-        self.rebuild_tail(first_removed);
+
+        impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> {
+            fn drop(&mut self) {
+                // data[..first_removed] is untouched, so we only need to
+                // rebuild the tail:
+                self.heap.rebuild_tail(self.first_removed);
+            }
+        }
     }
 }
 
diff --git a/library/alloc/src/collections/binary_heap/tests.rs b/library/alloc/src/collections/binary_heap/tests.rs
index ffbb6c8..500caa3 100644
--- a/library/alloc/src/collections/binary_heap/tests.rs
+++ b/library/alloc/src/collections/binary_heap/tests.rs
@@ -474,6 +474,25 @@
     assert!(a.is_empty());
 }
 
+#[test]
+fn test_retain_catch_unwind() {
+    let mut heap = BinaryHeap::from(vec![3, 1, 2]);
+
+    // Removes the 3, then unwinds out of retain.
+    let _ = catch_unwind(AssertUnwindSafe(|| {
+        heap.retain(|e| {
+            if *e == 1 {
+                panic!();
+            }
+            false
+        });
+    }));
+
+    // Naively this would be [1, 2] (an invalid heap) if BinaryHeap delegates to
+    // Vec's retain impl and then does not rebuild the heap after that unwinds.
+    assert_eq!(heap.into_vec(), [2, 1]);
+}
+
 // old binaryheap failed this test
 //
 // Integrity means that all elements are present after a comparison panics,
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index a07f3da..b279f21 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -378,8 +378,8 @@
 /// Currently, `Vec` does not guarantee the order in which elements are dropped.
 /// The order has changed in the past and may change again.
 ///
-/// [`get`]: ../../std/vec/struct.Vec.html#method.get
-/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut
+/// [`get`]: slice::get
+/// [`get_mut`]: slice::get_mut
 /// [`String`]: crate::string::String
 /// [`&str`]: type@str
 /// [`shrink_to_fit`]: Vec::shrink_to_fit
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 156b925..ae00232 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -278,6 +278,7 @@
 //!
 //! ```
 //! # #![allow(unused_must_use)]
+//! # #![cfg_attr(not(bootstrap), allow(map_unit_fn))]
 //! let v = vec![1, 2, 3, 4, 5];
 //! v.iter().map(|x| println!("{x}"));
 //! ```
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 9e3e13e..b8e7d0a 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -69,6 +69,7 @@
 #[doc(notable_trait)]
 #[rustc_diagnostic_item = "Iterator"]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[rustc_diagnostic_item = "IteratorItem"]
@@ -141,6 +142,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "iter_next_chunk", reason = "recently added", issue = "98326")]
+    #[rustc_do_not_const_check]
     fn next_chunk<const N: usize>(
         &mut self,
     ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
@@ -218,6 +220,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn size_hint(&self) -> (usize, Option<usize>) {
         (0, None)
     }
@@ -255,6 +258,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn count(self) -> usize
     where
         Self: Sized,
@@ -285,6 +289,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn last(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -331,6 +336,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
+    #[rustc_do_not_const_check]
     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
         for i in 0..n {
             self.next().ok_or(i)?;
@@ -379,6 +385,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn nth(&mut self, n: usize) -> Option<Self::Item> {
         self.advance_by(n).ok()?;
         self.next()
@@ -431,6 +438,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_step_by", since = "1.28.0")]
+    #[rustc_do_not_const_check]
     fn step_by(self, step: usize) -> StepBy<Self>
     where
         Self: Sized,
@@ -502,6 +510,7 @@
     /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
     where
         Self: Sized,
@@ -620,6 +629,7 @@
     /// [`zip`]: crate::iter::zip
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
     where
         Self: Sized,
@@ -662,6 +672,7 @@
     /// [`intersperse_with`]: Iterator::intersperse_with
     #[inline]
     #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+    #[rustc_do_not_const_check]
     fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
     where
         Self: Sized,
@@ -720,6 +731,7 @@
     /// [`intersperse`]: Iterator::intersperse
     #[inline]
     #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
+    #[rustc_do_not_const_check]
     fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
     where
         Self: Sized,
@@ -777,8 +789,10 @@
     ///     println!("{x}");
     /// }
     /// ```
+    #[rustc_diagnostic_item = "IteratorMap"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn map<B, F>(self, f: F) -> Map<Self, F>
     where
         Self: Sized,
@@ -824,6 +838,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_for_each", since = "1.21.0")]
+    #[rustc_do_not_const_check]
     fn for_each<F>(self, f: F)
     where
         Self: Sized,
@@ -899,6 +914,7 @@
     /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn filter<P>(self, predicate: P) -> Filter<Self, P>
     where
         Self: Sized,
@@ -944,6 +960,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
     where
         Self: Sized,
@@ -990,6 +1007,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn enumerate(self) -> Enumerate<Self>
     where
         Self: Sized,
@@ -1061,6 +1079,7 @@
     /// [`next`]: Iterator::next
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn peekable(self) -> Peekable<Self>
     where
         Self: Sized,
@@ -1126,6 +1145,7 @@
     #[inline]
     #[doc(alias = "drop_while")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
     where
         Self: Sized,
@@ -1207,6 +1227,7 @@
     /// the iteration should stop, but wasn't placed back into the iterator.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
     where
         Self: Sized,
@@ -1295,6 +1316,7 @@
     /// [`fuse`]: Iterator::fuse
     #[inline]
     #[stable(feature = "iter_map_while", since = "1.57.0")]
+    #[rustc_do_not_const_check]
     fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
     where
         Self: Sized,
@@ -1326,6 +1348,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn skip(self, n: usize) -> Skip<Self>
     where
         Self: Sized,
@@ -1379,6 +1402,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn take(self, n: usize) -> Take<Self>
     where
         Self: Sized,
@@ -1428,6 +1452,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
     where
         Self: Sized,
@@ -1468,6 +1493,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
     where
         Self: Sized,
@@ -1552,6 +1578,7 @@
     /// [`flat_map()`]: Iterator::flat_map
     #[inline]
     #[stable(feature = "iterator_flatten", since = "1.29.0")]
+    #[rustc_do_not_const_check]
     fn flatten(self) -> Flatten<Self>
     where
         Self: Sized,
@@ -1620,6 +1647,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn fuse(self) -> Fuse<Self>
     where
         Self: Sized,
@@ -1704,6 +1732,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn inspect<F>(self, f: F) -> Inspect<Self, F>
     where
         Self: Sized,
@@ -1734,6 +1763,7 @@
     /// assert_eq!(of_rust, vec!["of", "Rust"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn by_ref(&mut self) -> &mut Self
     where
         Self: Sized,
@@ -1853,6 +1883,7 @@
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
     #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")]
+    #[rustc_do_not_const_check]
     fn collect<B: FromIterator<Self::Item>>(self) -> B
     where
         Self: Sized,
@@ -1931,6 +1962,7 @@
     /// [`collect`]: Iterator::collect
     #[inline]
     #[unstable(feature = "iterator_try_collect", issue = "94047")]
+    #[rustc_do_not_const_check]
     fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
     where
         Self: Sized,
@@ -2004,6 +2036,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")]
+    #[rustc_do_not_const_check]
     fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
     where
         Self: Sized,
@@ -2038,6 +2071,7 @@
     /// assert_eq!(odd, vec![1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn partition<B, F>(self, f: F) -> (B, B)
     where
         Self: Sized,
@@ -2100,6 +2134,7 @@
     /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
     /// ```
     #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
+    #[rustc_do_not_const_check]
     fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
     where
         Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
@@ -2157,6 +2192,7 @@
     /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
     /// ```
     #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")]
+    #[rustc_do_not_const_check]
     fn is_partitioned<P>(mut self, mut predicate: P) -> bool
     where
         Self: Sized,
@@ -2251,6 +2287,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
     where
         Self: Sized,
@@ -2309,6 +2346,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
+    #[rustc_do_not_const_check]
     fn try_for_each<F, R>(&mut self, f: F) -> R
     where
         Self: Sized,
@@ -2428,6 +2466,7 @@
     #[doc(alias = "inject", alias = "foldl")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn fold<B, F>(mut self, init: B, mut f: F) -> B
     where
         Self: Sized,
@@ -2465,6 +2504,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_fold_self", since = "1.51.0")]
+    #[rustc_do_not_const_check]
     fn reduce<F>(mut self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -2536,6 +2576,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")]
+    #[rustc_do_not_const_check]
     fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>>
     where
         Self: Sized,
@@ -2593,6 +2634,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn all<F>(&mut self, f: F) -> bool
     where
         Self: Sized,
@@ -2646,6 +2688,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn any<F>(&mut self, f: F) -> bool
     where
         Self: Sized,
@@ -2709,6 +2752,7 @@
     /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         Self: Sized,
@@ -2740,6 +2784,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iterator_find_map", since = "1.30.0")]
+    #[rustc_do_not_const_check]
     fn find_map<B, F>(&mut self, f: F) -> Option<B>
     where
         Self: Sized,
@@ -2796,6 +2841,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "try_find", reason = "new API", issue = "63178")]
+    #[rustc_do_not_const_check]
     fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>>
     where
         Self: Sized,
@@ -2878,6 +2924,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn position<P>(&mut self, predicate: P) -> Option<usize>
     where
         Self: Sized,
@@ -2935,6 +2982,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn rposition<P>(&mut self, predicate: P) -> Option<usize>
     where
         P: FnMut(Self::Item) -> bool,
@@ -2986,6 +3034,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn max(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3024,6 +3073,7 @@
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn min(self) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3046,6 +3096,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    #[rustc_do_not_const_check]
     fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3079,6 +3130,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iter_max_by", since = "1.15.0")]
+    #[rustc_do_not_const_check]
     fn max_by<F>(self, compare: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3106,6 +3158,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    #[rustc_do_not_const_check]
     fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3139,6 +3192,7 @@
     /// ```
     #[inline]
     #[stable(feature = "iter_min_by", since = "1.15.0")]
+    #[rustc_do_not_const_check]
     fn min_by<F>(self, compare: F) -> Option<Self::Item>
     where
         Self: Sized,
@@ -3176,6 +3230,7 @@
     #[inline]
     #[doc(alias = "reverse")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn rev(self) -> Rev<Self>
     where
         Self: Sized + DoubleEndedIterator,
@@ -3214,6 +3269,7 @@
     /// assert_eq!(z, [3, 6]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
     where
         FromA: Default + Extend<A>,
@@ -3246,6 +3302,7 @@
     /// assert_eq!(v_map, vec![1, 2, 3]);
     /// ```
     #[stable(feature = "iter_copied", since = "1.36.0")]
+    #[rustc_do_not_const_check]
     fn copied<'a, T: 'a>(self) -> Copied<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
@@ -3293,6 +3350,7 @@
     /// assert_eq!(&[vec![23]], &faster[..]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_do_not_const_check]
     fn cloned<'a, T: 'a>(self) -> Cloned<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
@@ -3327,6 +3385,7 @@
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[rustc_do_not_const_check]
     fn cycle(self) -> Cycle<Self>
     where
         Self: Sized + Clone,
@@ -3370,6 +3429,7 @@
     /// ```
     #[track_caller]
     #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
+    #[rustc_do_not_const_check]
     fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
     where
         Self: Sized,
@@ -3400,6 +3460,7 @@
     /// assert_eq!(sum, 6);
     /// ```
     #[stable(feature = "iter_arith", since = "1.11.0")]
+    #[rustc_do_not_const_check]
     fn sum<S>(self) -> S
     where
         Self: Sized,
@@ -3429,6 +3490,7 @@
     /// assert_eq!(factorial(5), 120);
     /// ```
     #[stable(feature = "iter_arith", since = "1.11.0")]
+    #[rustc_do_not_const_check]
     fn product<P>(self) -> P
     where
         Self: Sized,
@@ -3450,6 +3512,7 @@
     /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn cmp<I>(self, other: I) -> Ordering
     where
         I: IntoIterator<Item = Self::Item>,
@@ -3479,6 +3542,7 @@
     /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
     where
         Self: Sized,
@@ -3535,6 +3599,7 @@
     /// ```
     ///
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn partial_cmp<I>(self, other: I) -> Option<Ordering>
     where
         I: IntoIterator,
@@ -3573,6 +3638,7 @@
     /// );
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
     where
         Self: Sized,
@@ -3606,6 +3672,7 @@
     /// assert_eq!([1].iter().eq([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn eq<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3631,6 +3698,7 @@
     /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
     /// ```
     #[unstable(feature = "iter_order_by", issue = "64295")]
+    #[rustc_do_not_const_check]
     fn eq_by<I, F>(self, other: I, eq: F) -> bool
     where
         Self: Sized,
@@ -3663,6 +3731,7 @@
     /// assert_eq!([1].iter().ne([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn ne<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3684,6 +3753,7 @@
     /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn lt<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3705,6 +3775,7 @@
     /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn le<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3726,6 +3797,7 @@
     /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn gt<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3747,6 +3819,7 @@
     /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
+    #[rustc_do_not_const_check]
     fn ge<I>(self, other: I) -> bool
     where
         I: IntoIterator,
@@ -3778,6 +3851,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted(self) -> bool
     where
         Self: Sized,
@@ -3806,6 +3880,7 @@
     ///
     /// [`is_sorted`]: Iterator::is_sorted
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted_by<F>(mut self, compare: F) -> bool
     where
         Self: Sized,
@@ -3852,6 +3927,7 @@
     /// ```
     #[inline]
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
+    #[rustc_do_not_const_check]
     fn is_sorted_by_key<F, K>(self, f: F) -> bool
     where
         Self: Sized,
@@ -3867,6 +3943,7 @@
     #[inline]
     #[doc(hidden)]
     #[unstable(feature = "trusted_random_access", issue = "none")]
+    #[rustc_do_not_const_check]
     unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item
     where
         Self: TrustedRandomAccessNoCoerce,
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index dc0702c..d3727a8 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -194,6 +194,7 @@
 #![feature(cfg_target_has_atomic_equal_alignment)]
 #![feature(const_closures)]
 #![feature(const_fn_floating_point_arithmetic)]
+#![feature(const_for)]
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 4ca4eb8..7b8062c 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -673,19 +673,23 @@
 fn break_patterns<T>(v: &mut [T]) {
     let len = v.len();
     if len >= 8 {
-        // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
-        let mut random = len as u32;
-        let mut gen_u32 = || {
-            random ^= random << 13;
-            random ^= random >> 17;
-            random ^= random << 5;
-            random
-        };
+        let mut seed = len;
         let mut gen_usize = || {
+            // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
             if usize::BITS <= 32 {
-                gen_u32() as usize
+                let mut r = seed as u32;
+                r ^= r << 13;
+                r ^= r >> 17;
+                r ^= r << 5;
+                seed = r as usize;
+                seed
             } else {
-                (((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize
+                let mut r = seed as u64;
+                r ^= r << 13;
+                r ^= r >> 7;
+                r ^= r << 17;
+                seed = r as usize;
+                seed
             }
         };
 
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 349cd91..311b2e2 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -43,7 +43,7 @@
 fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(target_os = "hermit")'.dependencies]
-hermit-abi = { version = "0.2.6", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 839fdc96..909d9bf 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1595,3 +1595,19 @@
     // Check for duplicate errors
     assert!(dir.filter(|e| e.is_err()).take(2).count() < 2);
 }
+
+#[test]
+fn rename_directory() {
+    let tmpdir = tmpdir();
+    let old_path = tmpdir.join("foo/bar/baz");
+    fs::create_dir_all(&old_path).unwrap();
+    let test_file = &old_path.join("temp.txt");
+
+    File::create(test_file).unwrap();
+
+    let new_path = tmpdir.join("quux/blat");
+    fs::create_dir_all(&new_path).unwrap();
+    fs::rename(&old_path, &new_path.join("newdir")).unwrap();
+    assert!(new_path.join("newdir").is_dir());
+    assert!(new_path.join("newdir/temp.txt").exists());
+}
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 439b8d5..258919d 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -9,7 +9,7 @@
 use crate::io;
 use crate::marker::PhantomData;
 use crate::mem::forget;
-#[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))]
+#[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))]
 use crate::sys::cvt;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
@@ -89,7 +89,7 @@
 impl BorrowedFd<'_> {
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(not(target_arch = "wasm32"))]
+    #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         // We want to atomically duplicate this file descriptor and set the
@@ -112,7 +112,7 @@
 
     /// Creates a new `OwnedFd` instance that shares the same underlying file
     /// description as the existing `BorrowedFd` instance.
-    #[cfg(target_arch = "wasm32")]
+    #[cfg(any(target_arch = "wasm32", target_os = "hermit"))]
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
         Err(crate::io::const_io_error!(
@@ -174,7 +174,10 @@
             // the file descriptor was closed or not, and if we retried (for
             // something like EINTR), we might close another valid file descriptor
             // opened after we closed ours.
+            #[cfg(not(target_os = "hermit"))]
             let _ = libc::close(self.fd);
+            #[cfg(target_os = "hermit")]
+            let _ = hermit_abi::close(self.fd);
         }
     }
 }
diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs
index c138162..0a4cefd 100644
--- a/library/std/src/os/fd/raw.rs
+++ b/library/std/src/os/fd/raw.rs
@@ -4,6 +4,9 @@
 
 use crate::fs;
 use crate::io;
+#[cfg(target_os = "hermit")]
+use crate::os::hermit::io::OwnedFd;
+#[cfg(not(target_os = "hermit"))]
 use crate::os::raw;
 #[cfg(all(doc, not(target_arch = "wasm32")))]
 use crate::os::unix::io::AsFd;
@@ -12,11 +15,18 @@
 #[cfg(target_os = "wasi")]
 use crate::os::wasi::io::OwnedFd;
 use crate::sys_common::{AsInner, IntoInner};
+#[cfg(target_os = "hermit")]
+use hermit_abi as libc;
 
 /// Raw file descriptors.
 #[rustc_allowed_through_unstable_modules]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(target_os = "hermit"))]
 pub type RawFd = raw::c_int;
+#[rustc_allowed_through_unstable_modules]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(target_os = "hermit")]
+pub type RawFd = i32;
 
 /// A trait to extract the raw file descriptor from an underlying object.
 ///
diff --git a/library/std/src/os/hermit/io/mod.rs b/library/std/src/os/hermit/io/mod.rs
new file mode 100644
index 0000000..524dfae
--- /dev/null
+++ b/library/std/src/os/hermit/io/mod.rs
@@ -0,0 +1,13 @@
+#![stable(feature = "os_fd", since = "1.66.0")]
+
+mod net;
+#[path = "../../fd/owned.rs"]
+mod owned;
+#[path = "../../fd/raw.rs"]
+mod raw;
+
+// Export the types and traits for the public API.
+#[stable(feature = "os_fd", since = "1.66.0")]
+pub use owned::*;
+#[stable(feature = "os_fd", since = "1.66.0")]
+pub use raw::*;
diff --git a/library/std/src/os/hermit/io/net.rs b/library/std/src/os/hermit/io/net.rs
new file mode 100644
index 0000000..8f3802d
--- /dev/null
+++ b/library/std/src/os/hermit/io/net.rs
@@ -0,0 +1,46 @@
+use crate::os::hermit::io::OwnedFd;
+use crate::os::hermit::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use crate::sys_common::{self, AsInner, FromInner, IntoInner};
+use crate::{net, sys};
+
+macro_rules! impl_as_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl AsRawFd for net::$t {
+            #[inline]
+            fn as_raw_fd(&self) -> RawFd {
+                self.as_inner().socket().as_raw_fd()
+            }
+        }
+    )*};
+}
+impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
+
+macro_rules! impl_from_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "from_raw_os", since = "1.1.0")]
+        impl FromRawFd for net::$t {
+            #[inline]
+            unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
+                unsafe {
+                    let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
+                    net::$t::from_inner(sys_common::net::$t::from_inner(socket))
+                }
+            }
+        }
+    )*};
+}
+impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
+
+macro_rules! impl_into_raw_fd {
+    ($($t:ident)*) => {$(
+        #[stable(feature = "into_raw_os", since = "1.4.0")]
+        impl IntoRawFd for net::$t {
+            #[inline]
+            fn into_raw_fd(self) -> RawFd {
+                self.into_inner().into_socket().into_inner().into_inner().into_raw_fd()
+            }
+        }
+    )*};
+}
+impl_into_raw_fd! { TcpStream TcpListener UdpSocket }
diff --git a/library/std/src/os/hermit/mod.rs b/library/std/src/os/hermit/mod.rs
index 4657b54..89b1b83 100644
--- a/library/std/src/os/hermit/mod.rs
+++ b/library/std/src/os/hermit/mod.rs
@@ -1,6 +1,11 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[allow(unused_extern_crates)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub extern crate hermit_abi as abi;
+
 pub mod ffi;
+pub mod io;
 
 /// A prelude for conveniently writing platform-specific code.
 ///
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 4277380..af137c9 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -60,16 +60,6 @@
         all(target_vendor = "fortanix", target_env = "sgx")
     )
 )))]
-#[cfg(target_os = "hermit")]
-#[path = "hermit/mod.rs"]
-pub mod unix;
-#[cfg(not(all(
-    doc,
-    any(
-        all(target_arch = "wasm32", not(target_os = "wasi")),
-        all(target_vendor = "fortanix", target_env = "sgx")
-    )
-)))]
 #[cfg(all(not(target_os = "hermit"), any(unix, doc)))]
 pub mod unix;
 
@@ -123,6 +113,8 @@
 pub mod fuchsia;
 #[cfg(target_os = "haiku")]
 pub mod haiku;
+#[cfg(target_os = "hermit")]
+pub mod hermit;
 #[cfg(target_os = "horizon")]
 pub mod horizon;
 #[cfg(target_os = "illumos")]
diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs
index afcae6c..220a76e 100644
--- a/library/std/src/sys/hermit/args.rs
+++ b/library/std/src/sys/hermit/args.rs
@@ -1,6 +1,6 @@
 use crate::ffi::{c_char, CStr, OsString};
 use crate::fmt;
-use crate::os::unix::ffi::OsStringExt;
+use crate::os::hermit::ffi::OsStringExt;
 use crate::ptr;
 use crate::sync::atomic::{
     AtomicIsize, AtomicPtr,
diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs
index c400f5f..3a2cdd3 100644
--- a/library/std/src/sys/hermit/fd.rs
+++ b/library/std/src/sys/hermit/fd.rs
@@ -1,36 +1,23 @@
 #![unstable(reason = "not public", issue = "none", feature = "fd")]
 
 use crate::io::{self, Read};
-use crate::mem;
+use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
 use crate::sys::unsupported;
-use crate::sys_common::AsInner;
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+
+use crate::os::hermit::io::*;
 
 #[derive(Debug)]
 pub struct FileDesc {
-    fd: i32,
+    fd: OwnedFd,
 }
 
 impl FileDesc {
-    pub fn new(fd: i32) -> FileDesc {
-        FileDesc { fd }
-    }
-
-    pub fn raw(&self) -> i32 {
-        self.fd
-    }
-
-    /// Extracts the actual file descriptor without closing it.
-    pub fn into_raw(self) -> i32 {
-        let fd = self.fd;
-        mem::forget(self);
-        fd
-    }
-
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        let result = unsafe { abi::read(self.fd, buf.as_mut_ptr(), buf.len()) };
-        cvt(result as i32)
+        let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?;
+        Ok(result as usize)
     }
 
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@@ -39,8 +26,8 @@
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        let result = unsafe { abi::write(self.fd, buf.as_ptr(), buf.len()) };
-        cvt(result as i32)
+        let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
+        Ok(result as usize)
     }
 
     pub fn duplicate(&self) -> io::Result<FileDesc> {
@@ -69,19 +56,45 @@
     }
 }
 
-impl AsInner<i32> for FileDesc {
-    fn as_inner(&self) -> &i32 {
+impl IntoInner<OwnedFd> for FileDesc {
+    fn into_inner(self) -> OwnedFd {
+        self.fd
+    }
+}
+
+impl FromInner<OwnedFd> for FileDesc {
+    fn from_inner(owned_fd: OwnedFd) -> Self {
+        Self { fd: owned_fd }
+    }
+}
+
+impl FromRawFd for FileDesc {
+    unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
+        Self { fd: FromRawFd::from_raw_fd(raw_fd) }
+    }
+}
+
+impl AsInner<OwnedFd> for FileDesc {
+    fn as_inner(&self) -> &OwnedFd {
         &self.fd
     }
 }
 
-impl Drop for FileDesc {
-    fn drop(&mut self) {
-        // Note that errors are ignored when closing a file descriptor. The
-        // reason for this is that if an error occurs we don't actually know if
-        // the file descriptor was closed or not, and if we retried (for
-        // something like EINTR), we might close another valid file descriptor
-        // (opened after we closed ours.
-        let _ = unsafe { abi::close(self.fd) };
+impl AsFd for FileDesc {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.fd.as_fd()
+    }
+}
+
+impl AsRawFd for FileDesc {
+    #[inline]
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for FileDesc {
+    fn into_raw_fd(self) -> RawFd {
+        self.fd.into_raw_fd()
     }
 }
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index 6fb92c0..c966f21 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -3,14 +3,17 @@
 use crate::hash::{Hash, Hasher};
 use crate::io::{self, Error, ErrorKind};
 use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
+use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::path::{Path, PathBuf};
 use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::cvt;
-use crate::sys::hermit::abi;
-use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
+use crate::sys::hermit::abi::{
+    self, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY,
+};
 use crate::sys::hermit::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
+use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
 pub use crate::sys_common::fs::{copy, try_exists};
 //pub use crate::sys_common::fs::remove_dir_all;
@@ -283,7 +286,7 @@
         }
 
         let fd = unsafe { cvt(abi::open(path.as_ptr(), flags, mode))? };
-        Ok(File(FileDesc::new(fd as i32)))
+        Ok(File(unsafe { FileDesc::from_raw_fd(fd as i32) }))
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
@@ -363,6 +366,54 @@
     }
 }
 
+impl AsInner<FileDesc> for File {
+    fn as_inner(&self) -> &FileDesc {
+        &self.0
+    }
+}
+
+impl AsInnerMut<FileDesc> for File {
+    fn as_inner_mut(&mut self) -> &mut FileDesc {
+        &mut self.0
+    }
+}
+
+impl IntoInner<FileDesc> for File {
+    fn into_inner(self) -> FileDesc {
+        self.0
+    }
+}
+
+impl FromInner<FileDesc> for File {
+    fn from_inner(file_desc: FileDesc) -> Self {
+        Self(file_desc)
+    }
+}
+
+impl AsFd for File {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.0.as_fd()
+    }
+}
+
+impl AsRawFd for File {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for File {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw_fd()
+    }
+}
+
+impl FromRawFd for File {
+    unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
+        Self(FromRawFd::from_raw_fd(raw_fd))
+    }
+}
+
 pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
     unsupported()
 }
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 20fd3dd..d34a4cf 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -13,7 +13,7 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
-#![allow(unsafe_op_in_unsafe_fn)]
+#![allow(missing_docs, nonstandard_style, unsafe_op_in_unsafe_fn)]
 
 use crate::intrinsics;
 use crate::os::raw::c_char;
@@ -57,9 +57,7 @@
 }
 
 use crate::io::ErrorKind;
-
-#[allow(unused_extern_crates)]
-pub extern crate hermit_abi as abi;
+use crate::os::hermit::abi;
 
 pub fn unsupported<T>() -> crate::io::Result<T> {
     Err(unsupported_err())
@@ -126,25 +124,72 @@
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno {
-        x if x == 13 as i32 => ErrorKind::PermissionDenied,
-        x if x == 98 as i32 => ErrorKind::AddrInUse,
-        x if x == 99 as i32 => ErrorKind::AddrNotAvailable,
-        x if x == 11 as i32 => ErrorKind::WouldBlock,
-        x if x == 103 as i32 => ErrorKind::ConnectionAborted,
-        x if x == 111 as i32 => ErrorKind::ConnectionRefused,
-        x if x == 104 as i32 => ErrorKind::ConnectionReset,
-        x if x == 17 as i32 => ErrorKind::AlreadyExists,
-        x if x == 4 as i32 => ErrorKind::Interrupted,
-        x if x == 22 as i32 => ErrorKind::InvalidInput,
-        x if x == 2 as i32 => ErrorKind::NotFound,
-        x if x == 107 as i32 => ErrorKind::NotConnected,
-        x if x == 1 as i32 => ErrorKind::PermissionDenied,
-        x if x == 32 as i32 => ErrorKind::BrokenPipe,
-        x if x == 110 as i32 => ErrorKind::TimedOut,
+        abi::errno::EACCES => ErrorKind::PermissionDenied,
+        abi::errno::EADDRINUSE => ErrorKind::AddrInUse,
+        abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        abi::errno::EAGAIN => ErrorKind::WouldBlock,
+        abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted,
+        abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused,
+        abi::errno::ECONNRESET => ErrorKind::ConnectionReset,
+        abi::errno::EEXIST => ErrorKind::AlreadyExists,
+        abi::errno::EINTR => ErrorKind::Interrupted,
+        abi::errno::EINVAL => ErrorKind::InvalidInput,
+        abi::errno::ENOENT => ErrorKind::NotFound,
+        abi::errno::ENOTCONN => ErrorKind::NotConnected,
+        abi::errno::EPERM => ErrorKind::PermissionDenied,
+        abi::errno::EPIPE => ErrorKind::BrokenPipe,
+        abi::errno::ETIMEDOUT => ErrorKind::TimedOut,
         _ => ErrorKind::Uncategorized,
     }
 }
 
-pub fn cvt(result: i32) -> crate::io::Result<usize> {
-    if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) }
+#[doc(hidden)]
+pub trait IsNegative {
+    fn is_negative(&self) -> bool;
+    fn negate(&self) -> i32;
+}
+
+macro_rules! impl_is_negative {
+    ($($t:ident)*) => ($(impl IsNegative for $t {
+        fn is_negative(&self) -> bool {
+            *self < 0
+        }
+
+        fn negate(&self) -> i32 {
+            i32::try_from(-(*self)).unwrap()
+        }
+    })*)
+}
+
+impl IsNegative for i32 {
+    fn is_negative(&self) -> bool {
+        *self < 0
+    }
+
+    fn negate(&self) -> i32 {
+        -(*self)
+    }
+}
+impl_is_negative! { i8 i16 i64 isize }
+
+pub fn cvt<T: IsNegative>(t: T) -> crate::io::Result<T> {
+    if t.is_negative() {
+        let e = decode_error_kind(t.negate());
+        Err(crate::io::Error::from(e))
+    } else {
+        Ok(t)
+    }
+}
+
+pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
+where
+    T: IsNegative,
+    F: FnMut() -> T,
+{
+    loop {
+        match cvt(f()) {
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+            other => return other,
+        }
+    }
 }
diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs
index 8a13879..5fb6281 100644
--- a/library/std/src/sys/hermit/net.rs
+++ b/library/std/src/sys/hermit/net.rs
@@ -1,129 +1,178 @@
-use crate::fmt;
-use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
-use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
-use crate::str;
-use crate::sync::Arc;
-use crate::sys::hermit::abi;
-use crate::sys::hermit::abi::IpAddress::{Ipv4, Ipv6};
-use crate::sys::unsupported;
-use crate::sys_common::AsInner;
+#![allow(dead_code)]
+
+use crate::cmp;
+use crate::io::{self, IoSlice, IoSliceMut};
+use crate::mem;
+use crate::net::{Shutdown, SocketAddr};
+use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd};
+use crate::sys::hermit::fd::FileDesc;
+use crate::sys::time::Instant;
+use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 
+use core::ffi::c_int;
+
+#[allow(unused_extern_crates)]
+pub extern crate hermit_abi as netc;
+
+pub use crate::sys::{cvt, cvt_r};
+
+pub type wrlen_t = usize;
+
+pub fn cvt_gai(err: i32) -> io::Result<()> {
+    if err == 0 {
+        return Ok(());
+    }
+
+    let detail = "";
+
+    Err(io::Error::new(
+        io::ErrorKind::Uncategorized,
+        &format!("failed to lookup address information: {detail}")[..],
+    ))
+}
+
 /// Checks whether the HermitCore's socket interface has been started already, and
 /// if not, starts it.
-pub fn init() -> io::Result<()> {
-    if abi::network_init() < 0 {
-        return Err(io::const_io_error!(
-            ErrorKind::Uncategorized,
-            "Unable to initialize network interface",
-        ));
-    }
-
-    Ok(())
-}
-
-#[derive(Debug, Clone)]
-pub struct Socket(abi::Handle);
-
-impl AsInner<abi::Handle> for Socket {
-    fn as_inner(&self) -> &abi::Handle {
-        &self.0
+pub fn init() {
+    if unsafe { netc::network_init() } < 0 {
+        panic!("Unable to initialize network interface");
     }
 }
 
-impl Drop for Socket {
-    fn drop(&mut self) {
-        let _ = abi::tcpstream::close(self.0);
+#[derive(Debug)]
+pub struct Socket(FileDesc);
+
+impl Socket {
+    pub fn new(addr: &SocketAddr, ty: i32) -> io::Result<Socket> {
+        let fam = match *addr {
+            SocketAddr::V4(..) => netc::AF_INET,
+            SocketAddr::V6(..) => netc::AF_INET6,
+        };
+        Socket::new_raw(fam, ty)
     }
-}
 
-// Arc is used to count the number of used sockets.
-// Only if all sockets are released, the drop
-// method will close the socket.
-#[derive(Clone)]
-pub struct TcpStream(Arc<Socket>);
+    pub fn new_raw(fam: i32, ty: i32) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
+    }
 
-impl TcpStream {
-    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        let addr = addr?;
+    pub fn new_pair(_fam: i32, _ty: i32) -> io::Result<(Socket, Socket)> {
+        unimplemented!()
+    }
 
-        match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
-            Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
-            _ => Err(io::const_io_error!(
-                ErrorKind::Uncategorized,
-                "Unable to initiate a connection on a socket",
-            )),
+    pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
+        self.set_nonblocking(true)?;
+        let r = unsafe {
+            let (addr, len) = addr.into_inner();
+            cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len))
+        };
+        self.set_nonblocking(false)?;
+
+        match r {
+            Ok(_) => return Ok(()),
+            // there's no ErrorKind for EINPROGRESS :(
+            Err(ref e) if e.raw_os_error() == Some(netc::errno::EINPROGRESS) => {}
+            Err(e) => return Err(e),
+        }
+
+        let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 };
+
+        if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+            return Err(io::const_io_error!(
+                io::ErrorKind::InvalidInput,
+                "cannot set a 0 duration timeout",
+            ));
+        }
+
+        let start = Instant::now();
+
+        loop {
+            let elapsed = start.elapsed();
+            if elapsed >= timeout {
+                return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out"));
+            }
+
+            let timeout = timeout - elapsed;
+            let mut timeout = timeout
+                .as_secs()
+                .saturating_mul(1_000)
+                .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
+            if timeout == 0 {
+                timeout = 1;
+            }
+
+            let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int;
+
+            match unsafe { netc::poll(&mut pollfd, 1, timeout) } {
+                -1 => {
+                    let err = io::Error::last_os_error();
+                    if err.kind() != io::ErrorKind::Interrupted {
+                        return Err(err);
+                    }
+                }
+                0 => {}
+                _ => {
+                    // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
+                    // for POLLHUP rather than read readiness
+                    if pollfd.revents & netc::POLLHUP != 0 {
+                        let e = self.take_error()?.unwrap_or_else(|| {
+                            io::const_io_error!(
+                                io::ErrorKind::Uncategorized,
+                                "no error set after POLLHUP",
+                            )
+                        });
+                        return Err(e);
+                    }
+
+                    return Ok(());
+                }
+            }
         }
     }
 
-    pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
-        match abi::tcpstream::connect(
-            saddr.ip().to_string().as_bytes(),
-            saddr.port(),
-            Some(duration.as_millis() as u64),
-        ) {
-            Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
-            _ => Err(io::const_io_error!(
-                ErrorKind::Uncategorized,
-                "Unable to initiate a connection on a socket",
-            )),
-        }
+    pub fn accept(
+        &self,
+        storage: *mut netc::sockaddr,
+        len: *mut netc::socklen_t,
+    ) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::accept(self.0.as_raw_fd(), storage, len) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
 
-    pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
-        abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64))
-            .map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value")
-            })
+    pub fn duplicate(&self) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::dup(self.0.as_raw_fd()) })?;
+        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
 
-    pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
-        abi::tcpstream::set_write_timeout(
-            *self.0.as_inner(),
-            duration.map(|d| d.as_millis() as u64),
-        )
-        .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value"))
+    fn recv_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<usize> {
+        let ret =
+            cvt(unsafe { netc::recv(self.0.as_raw_fd(), buf.as_mut_ptr(), buf.len(), flags) })?;
+        Ok(ret as usize)
     }
 
-    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
-        })?;
-
-        Ok(duration.map(|d| Duration::from_millis(d)))
-    }
-
-    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value")
-        })?;
-
-        Ok(duration.map(|d| Duration::from_millis(d)))
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.recv_with_flags(buf, 0)
     }
 
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
-        abi::tcpstream::peek(*self.0.as_inner(), buf)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peek failed"))
+        self.recv_with_flags(buf, netc::MSG_PEEK)
     }
 
-    pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
-        self.read_vectored(&mut [IoSliceMut::new(buffer)])
-    }
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let mut size: isize = 0;
 
-    pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        let mut size: usize = 0;
-
-        for i in ioslice.iter_mut() {
-            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to read on socket")
-            })?;
+        for i in bufs.iter_mut() {
+            let ret: isize =
+                cvt(unsafe { netc::read(self.0.as_raw_fd(), i.as_mut_ptr(), i.len()) })?;
 
             if ret != 0 {
                 size += ret;
             }
         }
 
-        Ok(size)
+        Ok(size.try_into().unwrap())
     }
 
     #[inline]
@@ -131,360 +180,174 @@
         true
     }
 
-    pub fn write(&self, buffer: &[u8]) -> io::Result<usize> {
-        self.write_vectored(&[IoSlice::new(buffer)])
+    fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
+        let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() };
+        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
+
+        let n = cvt(unsafe {
+            netc::recvfrom(
+                self.as_raw_fd(),
+                buf.as_mut_ptr(),
+                buf.len(),
+                flags,
+                &mut storage as *mut _ as *mut _,
+                &mut addrlen,
+            )
+        })?;
+        Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
     }
 
-    pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> {
-        let mut size: usize = 0;
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, 0)
+    }
 
-        for i in ioslice.iter() {
-            size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| {
-                io::const_io_error!(ErrorKind::Uncategorized, "Unable to write on socket")
-            })?;
+    pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, netc::MSG_PEEK)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
+        Ok(sz.try_into().unwrap())
+    }
+
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let mut size: isize = 0;
+
+        for i in bufs.iter() {
+            size += cvt(unsafe { netc::write(self.0.as_raw_fd(), i.as_ptr(), i.len()) })?;
         }
 
-        Ok(size)
+        Ok(size.try_into().unwrap())
     }
 
-    #[inline]
     pub fn is_write_vectored(&self) -> bool {
         true
     }
 
-    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"))?;
+    pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
+        let timeout = match dur {
+            Some(dur) => {
+                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
+                    return Err(io::const_io_error!(
+                        io::ErrorKind::InvalidInput,
+                        "cannot set a 0 duration timeout",
+                    ));
+                }
 
-        let saddr = match ipaddr {
-            Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
-            Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
-            _ => {
-                return Err(io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"));
+                let secs = if dur.as_secs() > netc::time_t::MAX as u64 {
+                    netc::time_t::MAX
+                } else {
+                    dur.as_secs() as netc::time_t
+                };
+                let mut timeout = netc::timeval {
+                    tv_sec: secs,
+                    tv_usec: dur.subsec_micros() as netc::suseconds_t,
+                };
+                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
+                    timeout.tv_usec = 1;
+                }
+                timeout
             }
+            None => netc::timeval { tv_sec: 0, tv_usec: 0 },
         };
 
-        Ok(saddr)
+        setsockopt(self, netc::SOL_SOCKET, kind, timeout)
     }
 
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
+    pub fn timeout(&self, kind: i32) -> io::Result<Option<Duration>> {
+        let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?;
+        if raw.tv_sec == 0 && raw.tv_usec == 0 {
+            Ok(None)
+        } else {
+            let sec = raw.tv_sec as u64;
+            let nsec = (raw.tv_usec as u32) * 1000;
+            Ok(Some(Duration::new(sec, nsec)))
+        }
     }
 
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
-        abi::tcpstream::shutdown(*self.0.as_inner(), how as i32)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to shutdown socket"))
+        let how = match how {
+            Shutdown::Write => netc::SHUT_WR,
+            Shutdown::Read => netc::SHUT_RD,
+            Shutdown::Both => netc::SHUT_RDWR,
+        };
+        cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
+        Ok(())
     }
 
-    pub fn duplicate(&self) -> io::Result<TcpStream> {
-        Ok(self.clone())
-    }
+    pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
+        let linger = netc::linger {
+            l_onoff: linger.is_some() as i32,
+            l_linger: linger.unwrap_or_default().as_secs() as libc::c_int,
+        };
 
-    pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> {
-        unsupported()
+        setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger)
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        unsupported()
+        let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?;
+
+        Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
-    pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
-        abi::tcpstream::set_nodelay(*self.0.as_inner(), mode)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "set_nodelay failed"))
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        let value: i32 = if nodelay { 1 } else { 0 };
+        setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value)
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        abi::tcpstream::nodelay(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "nodelay failed"))
+        let raw: i32 = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?;
+        Ok(raw != 0)
     }
 
-    pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
-        abi::tcpstream::set_tll(*self.0.as_inner(), tll)
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to set TTL"))
-    }
-
-    pub fn ttl(&self) -> io::Result<u32> {
-        abi::tcpstream::get_tll(*self.0.as_inner())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to get TTL"))
-    }
-
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
-    }
-
-    pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
-        abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode).map_err(|_| {
-            io::const_io_error!(ErrorKind::Uncategorized, "unable to set blocking mode")
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        let mut nonblocking: i32 = if nonblocking { 1 } else { 0 };
+        cvt(unsafe {
+            netc::ioctl(
+                self.as_raw_fd(),
+                netc::FIONBIO,
+                &mut nonblocking as *mut _ as *mut core::ffi::c_void,
+            )
         })
-    }
-}
-
-impl fmt::Debug for TcpStream {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
-    }
-}
-
-#[derive(Clone)]
-pub struct TcpListener(SocketAddr);
-
-impl TcpListener {
-    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        let addr = addr?;
-
-        Ok(TcpListener(*addr))
-    }
-
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        Ok(self.0)
-    }
-
-    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-        let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port())
-            .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "accept failed"))?;
-        let saddr = match ipaddr {
-            Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
-            Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
-            _ => {
-                return Err(io::const_io_error!(ErrorKind::Uncategorized, "accept failed"));
-            }
-        };
-
-        Ok((TcpStream(Arc::new(Socket(handle))), saddr))
-    }
-
-    pub fn duplicate(&self) -> io::Result<TcpListener> {
-        Ok(self.clone())
-    }
-
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn ttl(&self) -> io::Result<u32> {
-        unsupported()
-    }
-
-    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn only_v6(&self) -> io::Result<bool> {
-        unsupported()
+        .map(drop)
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
+        unimplemented!()
     }
 
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        unsupported()
+    // This is used by sys_common code to abstract over Windows and Unix.
+    pub fn as_raw(&self) -> RawFd {
+        self.0.as_raw_fd()
     }
 }
 
-impl fmt::Debug for TcpListener {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
+impl AsInner<FileDesc> for Socket {
+    fn as_inner(&self) -> &FileDesc {
+        &self.0
     }
 }
 
-pub struct UdpSocket(abi::Handle);
-
-impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        unsupported()
-    }
-
-    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
-    }
-
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        unsupported()
-    }
-
-    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        unsupported()
-    }
-
-    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-        unsupported()
-    }
-
-    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn duplicate(&self) -> io::Result<UdpSocket> {
-        unsupported()
-    }
-
-    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        unsupported()
-    }
-
-    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        unsupported()
-    }
-
-    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn broadcast(&self) -> io::Result<bool> {
-        unsupported()
-    }
-
-    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        unsupported()
-    }
-
-    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        unsupported()
-    }
-
-    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        unsupported()
-    }
-
-    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn ttl(&self) -> io::Result<u32> {
-        unsupported()
-    }
-
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unsupported()
-    }
-
-    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-        unsupported()
-    }
-
-    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-        unsupported()
-    }
-
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-        unsupported()
-    }
-}
-
-impl fmt::Debug for UdpSocket {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        Ok(())
-    }
-}
-
-pub struct LookupHost(!);
-
-impl LookupHost {
-    pub fn port(&self) -> u16 {
+impl IntoInner<FileDesc> for Socket {
+    fn into_inner(self) -> FileDesc {
         self.0
     }
 }
 
-impl Iterator for LookupHost {
-    type Item = SocketAddr;
-    fn next(&mut self) -> Option<SocketAddr> {
-        self.0
+impl FromInner<FileDesc> for Socket {
+    fn from_inner(file_desc: FileDesc) -> Self {
+        Self(file_desc)
     }
 }
 
-impl TryFrom<&str> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from(_v: &str) -> io::Result<LookupHost> {
-        unsupported()
+impl AsFd for Socket {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.0.as_fd()
     }
 }
 
-impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
-        unsupported()
+impl AsRawFd for Socket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
     }
 }
-
-#[allow(nonstandard_style)]
-pub mod netc {
-    pub const AF_INET: u8 = 0;
-    pub const AF_INET6: u8 = 1;
-    pub type sa_family_t = u8;
-
-    #[derive(Copy, Clone)]
-    pub struct in_addr {
-        pub s_addr: u32,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr_in {
-        pub sin_family: sa_family_t,
-        pub sin_port: u16,
-        pub sin_addr: in_addr,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct in6_addr {
-        pub s6_addr: [u8; 16],
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr_in6 {
-        pub sin6_family: sa_family_t,
-        pub sin6_port: u16,
-        pub sin6_addr: in6_addr,
-        pub sin6_flowinfo: u32,
-        pub sin6_scope_id: u32,
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct sockaddr {}
-}
diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs
index 8f927df..e53dbae 100644
--- a/library/std/src/sys/hermit/os.rs
+++ b/library/std/src/sys/hermit/os.rs
@@ -4,7 +4,7 @@
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
-use crate::os::unix::ffi::OsStringExt;
+use crate::os::hermit::ffi::OsStringExt;
 use crate::path::{self, PathBuf};
 use crate::str;
 use crate::sync::Mutex;
diff --git a/library/std/src/sys/hermit/time.rs b/library/std/src/sys/hermit/time.rs
index c17e6c8..32ddc43 100644
--- a/library/std/src/sys/hermit/time.rs
+++ b/library/std/src/sys/hermit/time.rs
@@ -1,6 +1,7 @@
 #![allow(dead_code)]
 
 use crate::cmp::Ordering;
+use crate::ops::{Add, AddAssign, Sub, SubAssign};
 use crate::sys::hermit::abi;
 use crate::sys::hermit::abi::timespec;
 use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
@@ -102,55 +103,122 @@
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
-pub struct Instant {
-    t: Timespec,
-}
+pub struct Instant(Timespec);
 
 impl Instant {
     pub fn now() -> Instant {
         let mut time: Timespec = Timespec::zero();
         let _ = unsafe { abi::clock_gettime(CLOCK_MONOTONIC, &mut time.t as *mut timespec) };
 
-        Instant { t: time }
+        Instant(time)
+    }
+
+    #[stable(feature = "time2", since = "1.8.0")]
+    pub fn elapsed(&self) -> Duration {
+        Instant::now() - *self
+    }
+
+    pub fn duration_since(&self, earlier: Instant) -> Duration {
+        self.checked_duration_since(earlier).unwrap_or_default()
+    }
+
+    pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
+        self.checked_sub_instant(&earlier)
     }
 
     pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
-        self.t.sub_timespec(&other.t).ok()
+        self.0.sub_timespec(&other.0).ok()
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_add_duration(other)? })
+        Some(Instant(self.0.checked_add_duration(other)?))
     }
 
     pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_sub_duration(other)? })
+        Some(Instant(self.0.checked_sub_duration(other)?))
+    }
+
+    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_add_duration(&duration).map(Instant)
+    }
+
+    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
+        self.0.checked_sub_duration(&duration).map(Instant)
+    }
+}
+
+impl Add<Duration> for Instant {
+    type Output = Instant;
+
+    /// # Panics
+    ///
+    /// This function may panic if the resulting point in time cannot be represented by the
+    /// underlying data structure. See [`Instant::checked_add`] for a version without panic.
+    fn add(self, other: Duration) -> Instant {
+        self.checked_add(other).expect("overflow when adding duration to instant")
+    }
+}
+
+impl AddAssign<Duration> for Instant {
+    fn add_assign(&mut self, other: Duration) {
+        *self = *self + other;
+    }
+}
+
+impl Sub<Duration> for Instant {
+    type Output = Instant;
+
+    fn sub(self, other: Duration) -> Instant {
+        self.checked_sub(other).expect("overflow when subtracting duration from instant")
+    }
+}
+
+impl SubAssign<Duration> for Instant {
+    fn sub_assign(&mut self, other: Duration) {
+        *self = *self - other;
+    }
+}
+
+impl Sub<Instant> for Instant {
+    type Output = Duration;
+
+    /// Returns the amount of time elapsed from another instant to this one,
+    /// or zero duration if that instant is later than this one.
+    ///
+    /// # Panics
+    ///
+    /// Previous rust versions panicked when `other` was later than `self`. Currently this
+    /// method saturates. Future versions may reintroduce the panic in some circumstances.
+    /// See [Monotonicity].
+    ///
+    /// [Monotonicity]: Instant#monotonicity
+    fn sub(self, other: Instant) -> Duration {
+        self.duration_since(other)
     }
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub struct SystemTime {
-    t: Timespec,
-}
+pub struct SystemTime(Timespec);
 
-pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
+pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
 
 impl SystemTime {
     pub fn now() -> SystemTime {
         let mut time: Timespec = Timespec::zero();
         let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, &mut time.t as *mut timespec) };
 
-        SystemTime { t: time }
+        SystemTime(time)
     }
 
     pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.t.sub_timespec(&other.t)
+        self.0.sub_timespec(&other.0)
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_add_duration(other)? })
+        Some(SystemTime(self.0.checked_add_duration(other)?))
     }
 
     pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_sub_duration(other)? })
+        Some(SystemTime(self.0.checked_sub_duration(other)?))
     }
 }
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index f58dcf1..1d0ab77 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -539,14 +539,6 @@
     pub PathBuffer: WCHAR,
 }
 
-/// NB: Use carefully! In general using this as a reference is likely to get the
-/// provenance wrong for the `PathBuffer` field!
-#[repr(C)]
-pub struct FILE_NAME_INFO {
-    pub FileNameLength: DWORD,
-    pub FileName: [WCHAR; 1],
-}
-
 #[repr(C)]
 pub struct MOUNT_POINT_REPARSE_BUFFER {
     pub SubstituteNameOffset: c_ushort,
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index 2cc34c9..7fdd1f7 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -2,8 +2,7 @@
 use crate::mem::size_of;
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
 use crate::slice;
-use crate::sys::{c, Align8};
-use core;
+use crate::sys::c;
 use libc;
 
 #[derive(Copy, Clone)]
@@ -125,22 +124,33 @@
         return false;
     }
 
-    const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>();
-    let mut name_info_bytes = Align8([0u8; SIZE]);
+    /// Mirrors [`FILE_NAME_INFO`], giving it a fixed length that we can stack
+    /// allocate
+    ///
+    /// [`FILE_NAME_INFO`]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_name_info
+    #[repr(C)]
+    #[allow(non_snake_case)]
+    struct FILE_NAME_INFO {
+        FileNameLength: u32,
+        FileName: [u16; c::MAX_PATH as usize],
+    }
+    let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] };
+    // Safety: buffer length is fixed.
     let res = c::GetFileInformationByHandleEx(
         handle,
         c::FileNameInfo,
-        name_info_bytes.0.as_mut_ptr() as *mut libc::c_void,
-        SIZE as u32,
+        &mut name_info as *mut _ as *mut libc::c_void,
+        size_of::<FILE_NAME_INFO>() as u32,
     );
     if res == 0 {
         return false;
     }
-    let name_info: &c::FILE_NAME_INFO = &*(name_info_bytes.0.as_ptr() as *const c::FILE_NAME_INFO);
-    let name_len = name_info.FileNameLength as usize / 2;
-    // Offset to get the `FileName` field.
-    let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>();
-    let s = core::slice::from_raw_parts(name_ptr, name_len);
+
+    // Use `get` because `FileNameLength` can be out of range.
+    let s = match name_info.FileName.get(..name_info.FileNameLength as usize / 2) {
+        None => return false,
+        Some(s) => s,
+    };
     let name = String::from_utf16_lossy(s);
     // Get the file name only.
     let name = name.rsplit('\\').next().unwrap_or(&name);
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 6b24b0e..e9c727c 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -44,7 +44,6 @@
 
 cfg_if::cfg_if! {
     if #[cfg(any(target_os = "l4re",
-                 target_os = "hermit",
                  feature = "restricted-std",
                  all(target_family = "wasm", not(target_os = "emscripten")),
                  all(target_vendor = "fortanix", target_env = "sgx")))] {
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index acf9c29..5c2e9da 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -352,7 +352,7 @@
         self.checked_duration_since(earlier).unwrap_or_default()
     }
 
-    /// Returns the amount of time elapsed since this instant was created.
+    /// Returns the amount of time elapsed since this instant.
     ///
     /// # Panics
     ///
@@ -525,8 +525,8 @@
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
-    /// Returns the difference between the clock time when this
-    /// system time was created, and the current clock time.
+    /// Returns the difference from this system time to the
+    /// current clock time.
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs
new file mode 100644
index 0000000..fce2202
--- /dev/null
+++ b/library/std/tests/common/mod.rs
@@ -0,0 +1,58 @@
+#![allow(unused)]
+
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::thread;
+use rand::RngCore;
+
+/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
+/// seed not being the same for every RNG invocation too.
+#[track_caller]
+pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
+    use core::hash::{BuildHasher, Hash, Hasher};
+    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
+    core::panic::Location::caller().hash(&mut hasher);
+    let hc64 = hasher.finish();
+    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
+    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
+    rand::SeedableRng::from_seed(seed)
+}
+
+// Copied from std::sys_common::io
+pub struct TempDir(PathBuf);
+
+impl TempDir {
+    pub fn join(&self, path: &str) -> PathBuf {
+        let TempDir(ref p) = *self;
+        p.join(path)
+    }
+
+    pub fn path(&self) -> &Path {
+        let TempDir(ref p) = *self;
+        p
+    }
+}
+
+impl Drop for TempDir {
+    fn drop(&mut self) {
+        // Gee, seeing how we're testing the fs module I sure hope that we
+        // at least implement this correctly!
+        let TempDir(ref p) = *self;
+        let result = fs::remove_dir_all(p);
+        // Avoid panicking while panicking as this causes the process to
+        // immediately abort, without displaying test results.
+        if !thread::panicking() {
+            result.unwrap();
+        }
+    }
+}
+
+#[track_caller] // for `test_rng`
+pub fn tmpdir() -> TempDir {
+    let p = env::temp_dir();
+    let mut r = test_rng();
+    let ret = p.join(&format!("rust-{}", r.next_u32()));
+    fs::create_dir(&ret).unwrap();
+    TempDir(ret)
+}
diff --git a/library/std/tests/create_dir_all_bare.rs b/library/std/tests/create_dir_all_bare.rs
new file mode 100644
index 0000000..fe78932
--- /dev/null
+++ b/library/std/tests/create_dir_all_bare.rs
@@ -0,0 +1,39 @@
+#![cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
+
+//! Note that this test changes the current directory so
+//! should not be in the same process as other tests.
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+
+mod common;
+
+// On some platforms, setting the current directory will prevent deleting it.
+// So this helper ensures the current directory is reset.
+struct CurrentDir(PathBuf);
+impl CurrentDir {
+    fn new() -> Self {
+        Self(env::current_dir().unwrap())
+    }
+    fn set(&self, path: &Path) {
+        env::set_current_dir(path).unwrap();
+    }
+    fn with(path: &Path, f: impl FnOnce()) {
+        let current_dir = Self::new();
+        current_dir.set(path);
+        f();
+    }
+}
+impl Drop for CurrentDir {
+    fn drop(&mut self) {
+        env::set_current_dir(&self.0).unwrap();
+    }
+}
+
+#[test]
+fn create_dir_all_bare() {
+    let tmpdir = common::tmpdir();
+    CurrentDir::with(tmpdir.path(), || {
+        fs::create_dir_all("create-dir-all-bare").unwrap();
+    });
+}
diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs
index aae2c49..96b4f37 100644
--- a/library/std/tests/env.rs
+++ b/library/std/tests/env.rs
@@ -3,18 +3,8 @@
 
 use rand::distributions::{Alphanumeric, DistString};
 
-/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
-/// seed not being the same for every RNG invocation too.
-#[track_caller]
-pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
-    use core::hash::{BuildHasher, Hash, Hasher};
-    let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
-    core::panic::Location::caller().hash(&mut hasher);
-    let hc64 = hasher.finish();
-    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
-    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
-    rand::SeedableRng::from_seed(seed)
-}
+mod common;
+use common::test_rng;
 
 #[track_caller]
 fn make_rand_name() -> OsString {
diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml
index 61b6f33..18cb023 100644
--- a/library/test/Cargo.toml
+++ b/library/test/Cargo.toml
@@ -7,11 +7,9 @@
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
 std = { path = "../std" }
 core = { path = "../core" }
-libc = { version = "0.2", default-features = false }
 panic_unwind = { path = "../panic_unwind" }
 panic_abort = { path = "../panic_abort" }
 
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 6157949..ae72a42 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -218,7 +218,7 @@
                     WalkBuilder::new(first)
                 }
             } else {
-                WalkBuilder::new(first)
+                WalkBuilder::new(src.join(first))
             };
 
             for path in &paths[1..] {
@@ -229,7 +229,7 @@
                         walker.add(path);
                     }
                 } else {
-                    walker.add(path);
+                    walker.add(src.join(path));
                 }
             }
 
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index 94ec240..9c550b2 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.14.3
\ No newline at end of file
+0.14.4
\ No newline at end of file
diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py
index a6d84a3..c3d532c 100755
--- a/src/ci/docker/scripts/fuchsia-test-runner.py
+++ b/src/ci/docker/scripts/fuchsia-test-runner.py
@@ -507,9 +507,8 @@
     bin/{exe_name}={bin_path}
     lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
     lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
-    lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so
-    lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so
-    lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so
+    lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
+    lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
     """
 
     TEST_ENV_VARS: ClassVar[List[str]] = [
@@ -844,23 +843,34 @@
             "--",
             "--build-id-dir",
             os.path.join(self.sdk_dir, ".build-id"),
-            "--build-id-dir",
-            os.path.join(self.libs_dir(), ".build-id"),
         ]
 
-        # Add rust source if it's available
-        if args.rust_src is not None:
+        libs_build_id_path = os.path.join(self.libs_dir(), ".build-id")
+        if os.path.exists(libs_build_id_path):
+            # Add .build-id symbols if installed libs have been stripped into a
+            # .build-id directory
             command += [
-                "--build-dir",
-                args.rust_src,
+                "--build-id-dir",
+                libs_build_id_path,
+            ]
+        else:
+            # If no .build-id directory is detected, then assume that the shared
+            # libs contain their debug symbols
+            command += [
+                f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib",
             ]
 
+        # Add rust source if it's available
+        rust_src_map = None
+        if args.rust_src is not None:
+            # This matches the remapped prefix used by compiletest. There's no
+            # clear way that we can determine this, so it's hard coded.
+            rust_src_map = f"/rustc/FAKE_PREFIX={args.rust_src}"
+
         # Add fuchsia source if it's available
+        fuchsia_src_map = None
         if args.fuchsia_src is not None:
-            command += [
-                "--build-dir",
-                os.path.join(args.fuchsia_src, "out", "default"),
-            ]
+            fuchsia_src_map = f"./../..={args.fuchsia_src}"
 
         # Load debug symbols for the test binary and automatically attach
         if args.test is not None:
@@ -883,7 +893,28 @@
                 test_name,
             )
 
+            # The fake-test-src-base directory maps to the suite directory
+            # e.g. tests/ui/foo.rs has a path of rust/fake-test-src-base/foo.rs
+            fake_test_src_base = os.path.join(
+                args.rust_src,
+                "fake-test-src-base",
+            )
+            real_test_src_base = os.path.join(
+                args.rust_src,
+                "tests",
+                args.test.split(os.path.sep)[0],
+            )
+            test_src_map = f"{fake_test_src_base}={real_test_src_base}"
+
             with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f:
+                print(f"set source-map += {test_src_map}", file=f)
+
+                if rust_src_map is not None:
+                    print(f"set source-map += {rust_src_map}", file=f)
+
+                if fuchsia_src_map is not None:
+                    print(f"set source-map += {fuchsia_src_map}", file=f)
+
                 print(f"attach {test_name[:31]}", file=f)
 
             command += [
@@ -900,6 +931,20 @@
         # Connect to the running emulator with zxdb
         subprocess.run(command, env=self.ffx_cmd_env(), check=False)
 
+    def syslog(self, args):
+        subprocess.run(
+            [
+                self.tool_path("ffx"),
+                "--config",
+                self.ffx_user_config_path(),
+                "log",
+                "--since",
+                "now",
+            ],
+            env=self.ffx_cmd_env(),
+            check=False,
+        )
+
 
 def start(args):
     test_env = TestEnvironment.from_args(args)
@@ -933,6 +978,12 @@
     return 0
 
 
+def syslog(args):
+    test_env = TestEnvironment.read_from_file()
+    test_env.syslog(args)
+    return 0
+
+
 def main():
     parser = argparse.ArgumentParser()
 
@@ -1028,6 +1079,11 @@
     )
     debug_parser.set_defaults(func=debug)
 
+    syslog_parser = subparsers.add_parser(
+        "syslog", help="prints the device syslog"
+    )
+    syslog_parser.set_defaults(func=syslog)
+
     args = parser.parse_args()
     return args.func(args)
 
diff --git a/src/doc/index.md b/src/doc/index.md
index bf08960..7c97c16 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -4,6 +4,20 @@
 nav {
     display: none;
 }
+body {
+    font-family: serif;
+}
+h1, h2, h3, h4, h5, h6 {
+    font-family: sans-serif;
+}
+h3 {
+    font-size: 1.35rem;
+}
+h4 {
+    font-size: 1.1rem;
+}
+
+/* Formatting for docs search bar */
 #search-input {
     width: calc(100% - 58px);
 }
@@ -21,53 +35,74 @@
 #search-but:hover, #search-input:focus {
     border-color: #55a9ff;
 }
-h2 {
-    font-size: 18px;
+
+/* Formatting for external link icon */
+svg.external-link {
+  display: inline-block;
+  position: relative;
+  vertical-align: super;
+  width: 0.7rem;
+  height: 0.7rem;
+  padding-left: 2px;
+  top: 3px;
 }
 </style>
 
-Welcome to an overview of the documentation provided by the [Rust project].
-All of these projects are managed by the Docs Team; there are other
-unofficial documentation resources as well!
+Welcome to an overview of the documentation provided by the [Rust
+project]. This page contains links to various helpful references,
+most of which are available offline (if opened with `rustup doc`). Many of these
+resources take the form of "books"; we collectively call these "The Rust
+Bookshelf." Some are large, some are small.
 
-Many of these resources take the form of "books"; we collectively call these
-"The Rust Bookshelf." Some are large, some are small.
+All of these books are managed by the Rust Organization, but other unofficial
+documentation resources are included here as well!
 
-# Learn Rust
+If you're just looking for the standard library reference, here it is:
+[Rust API documentation](std/index.html)
 
-If you'd like to learn Rust, this is the spot for you! All of these resources
+
+## Learning Rust
+
+If you'd like to learn Rust, this is the section for you! All of these resources
 assume that you have programmed before, but not in any specific language:
 
-## The Rust Programming Language
+### The Rust Programming Language
 
-Affectionately nicknamed "the book," [The Rust Programming
-Language](book/index.html) will give you an overview of the language from
-first principles. You'll build a few projects along the way, and by the end,
-you'll have a solid grasp of the language.
+Affectionately nicknamed "the book," [The Rust Programming Language](book/index.html)
+will give you an overview of the language from first principles. You'll build a
+few projects along the way, and by the end, you'll have a solid grasp of how to
+use the language.
 
-## Rust By Example
+### Rust By Example
 
 If reading multiple hundreds of pages about a language isn't your style, then
-[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with
-a lot of words, RBE shows off a bunch of code, and keeps the talking to a
-minimum. It also includes exercises!
+[Rust By Example](rust-by-example/index.html) has you covered. RBE shows off a
+bunch of code without using a lot of words. It also includes exercises!
 
-## Rustlings
+### Rustlings
 
-[Rustlings](https://github.com/rust-lang/rustlings) guides you through downloading and setting up the Rust toolchain,
-and teaches you the basics of reading and writing Rust syntax. It's an
-alternative to Rust by Example that works with your own environment.
+[Rustlings](https://github.com/rust-lang/rustlings) guides you
+through downloading and setting up the Rust toolchain, then provides an
+interactive tool that teaches you how to solve coding challenges in Rust.
 
-# Use Rust
+### Rust Playground
 
-Once you've gotten familiar with the language, these resources can help you
-when you're actually using it day-to-day.
+The [Rust Playground](https://play.rust-lang.org) is a great place
+to try out and share small bits of code, or experiment with some of the most
+popular crates.
 
-## The Standard Library
 
-Rust's standard library has [extensive API documentation](std/index.html),
-with explanations of how to use various things, as well as example code for
-accomplishing various tasks.
+## Using Rust
+
+Once you've gotten familiar with the language, these resources can help you put
+it to work.
+
+### The Standard Library
+
+Rust's standard library has [extensive API documentation](std/index.html), with
+explanations of how to use various things, as well as example code for
+accomplishing various tasks. Code examples have a "Run" button on hover that
+opens the sample in the playground.
 
 <div>
   <form action="std/index.html" method="get">
@@ -77,76 +112,143 @@
   </form>
 </div>
 
-## The Edition Guide
+### Your Personal Documentation
 
-[The Edition Guide](edition-guide/index.html) describes the Rust editions.
+Whenever you are working in a crate, `cargo doc --open` will generate
+documentation for your project _and_ all its dependencies in their correct
+version, and open it in your browser. Add the flag `--document-private-items` to
+also show items not marked `pub`.
 
-## The Rustc Book
+### The Edition Guide
 
-[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`.
+[The Edition Guide](edition-guide/index.html) describes the Rust editions and
+their differences.
 
-## The Cargo Book
+### The `rustc` Book
 
-[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager.
+[The `rustc` Book](rustc/index.html) describes the Rust compiler, `rustc`.
 
-## The Rustdoc Book
+### The Cargo Book
+
+[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and
+dependency manager.
+
+### The Rustdoc Book
 
 [The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`.
 
-## The Clippy Book
+### The Clippy Book
 
 [The Clippy Book](clippy/index.html) describes our static analyzer, Clippy.
 
-## Extended Error Listing
+### Extended Error Listing
 
 Many of Rust's errors come with error codes, and you can request extended
-diagnostics from the compiler on those errors. You can also [read them
-here](error_codes/index.html), if you prefer to read them that way.
+diagnostics from the compiler on those errors (with `rustc --explain`). You can
+also read them here if you prefer: [rustc error codes](error_codes/index.html)
 
-# Master Rust
+
+## Mastering Rust
 
 Once you're quite familiar with the language, you may find these advanced
 resources useful.
 
-## The Reference
+### The Reference
 
-[The Reference](reference/index.html) is not a formal spec, but is more detailed and
-comprehensive than the book.
+[The Reference](reference/index.html) is not a formal spec, but is more detailed
+and comprehensive than the book.
 
-## The Style Guide
+### The Style Guide
 
-[The Rust Style Guide](style-guide/index.html) describes the standard formatting of Rust
-code. Most developers use rustfmt to format their code, and rustfmt's default
-formatting matches this style guide.
+[The Rust Style Guide](style-guide/index.html) describes the standard formatting
+of Rust code. Most developers use `cargo fmt` to invoke `rustfmt` and format the
+code automatically (the result matches this style guide).
 
-## The Rustonomicon
+### The Rustonomicon
 
-[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe
-Rust. It's also sometimes called "the 'nomicon."
+[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of
+unsafe Rust. It's also sometimes called "the 'nomicon."
 
-## The Unstable Book
+### The Unstable Book
 
-[The Unstable Book](unstable-book/index.html) has documentation for unstable features.
+[The Unstable Book](unstable-book/index.html) has documentation for unstable
+features.
 
-## The `rustc` Contribution Guide
+### The `rustc` Contribution Guide
 
-[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) documents how
-the compiler works and how to contribute to it. This is useful if you want to build
-or modify the Rust compiler from source (e.g. to target something non-standard).
+[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/)
+documents how the compiler works and how to contribute to it. This is useful if
+you want to build or modify the Rust compiler from source (e.g. to target
+something non-standard).
 
-# Specialize Rust
 
-When using Rust in specific domain areas, consider using the following resources tailored to each domain.
+## Specialized Rust
 
-## Embedded Systems
+When using Rust in specific domains, consider using the following resources
+tailored to each area.
 
-When developing for Bare Metal or Embedded Linux systems, you may find these resources maintained by the [Embedded Working Group] useful.
+### Embedded Systems
+
+When developing for Bare Metal or Embedded Linux systems, you may find these
+resources maintained by the [Embedded Working Group] useful.
 
 [Embedded Working Group]: https://github.com/rust-embedded
 
-### The Embedded Rust Book
+#### The Embedded Rust Book
 
-[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development.
+[The Embedded Rust Book] is targeted at developers familiar with embedded
+development and familiar with Rust, but have not used Rust for embedded
+development.
 
 [The Embedded Rust Book]: embedded-book/index.html
 [Rust project]: https://www.rust-lang.org
+
+<script>
+// check if a given link is external
+function isExternalLink(url) {
+  const tmp = document.createElement('a');
+  tmp.href = url;
+  return tmp.host !== window.location.host;
+}
+
+// Add the `external` class to all <a> tags with external links and append the external link SVG
+function updateExternalAnchors() {
+  /*
+    External link SVG from Font-Awesome
+    CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0
+    via Wikimedia Commons
+  */
+  const svgText = `<svg
+     class='external-link'
+     xmlns='http://www.w3.org/2000/svg'
+     viewBox='0 -256 1850 1850'
+     width='100%'
+     height='100%'>
+       <g transform='matrix(1,0,0,-1,30,1427)'>
+         <path d='M 1408,608 V 288 Q 1408,169 1323.5,84.5 1239,0 1120,
+           0 H 288 Q 169,0 84.5,84.5 0,169 0,288 v 832 Q 0,1239 84.5,1323.5 169,
+           1408 288,1408 h 704 q 14,0 23,-9 9,-9 9,-23 v -64 q 0,-14 -9,-23 -9,
+           -9 -23,-9 H 288 q -66,0 -113,-47 -47,-47 -47,-113 V 288 q 0,-66 47,
+           -113 47,-47 113,-47 h 832 q 66,0 113,47 47,47 47,113 v 320 q 0,14 9,
+           23 9,9 23,9 h 64 q 14,0 23,-9 9,-9 9,-23 z m 384,864 V 960 q 0,
+           -26 -19,-45 -19,-19 -45,-19 -26,0 -45,19 L 1507,1091 855,439 q -10,
+           -10 -23,-10 -13,0 -23,10 L 695,553 q -10,10 -10,23 0,13 10,23 l 652,
+           652 -176,176 q -19,19 -19,45 0,26 19,45 19,19 45,19 h 512 q 26,0 45,
+           -19 19,-19 19,-45 z' style='fill:currentColor' />
+         </g>
+     </svg>`;
+  let allAnchors = document.getElementsByTagName("a");
+
+  for (var i = 0; i < allAnchors.length; ++i) {
+    let anchor = allAnchors[i];
+    if (isExternalLink(anchor.href)) {
+      anchor.classList.add("external");
+      anchor.innerHTML += svgText;
+    }
+  }
+}
+
+// on page load, update external anchors
+document.addEventListener("DOMContentLoaded", updateExternalAnchors);
+
+</script>
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 0f165b2..63dde2a 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -687,7 +687,9 @@
 for the steps to build locally.
 
 You'll also need to download a copy of the Fuchsia SDK. The current minimum
-supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1).
+supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version].
+
+[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89
 
 Fuchsia's test runner interacts with the Fuchsia emulator and is located at
 `src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our
@@ -697,7 +699,7 @@
 src/ci/docker/scripts/fuchsia-test-runner.py start
     --rust ${RUST_SRC_PATH}/install
     --sdk ${SDK_PATH}
-    --target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
+    --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
 ```
 
 Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
@@ -717,17 +719,11 @@
     --target x86_64-unknown-fuchsia                                           \
     --run=always --jobs 1                                                     \
     --test-args --target-rustcflags                                           \
-    --test-args -L                                                            \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
     --test-args --target-rustcflags                                           \
-    --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib                      \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
     --test-args --target-rustcflags                                           \
-    --test-args -L                                                            \
-    --test-args --target-rustcflags                                           \
-    --test-args ${SDK_PATH}/arch/{x64|arm64}/lib                              \
-    --test-args --target-rustcflags                                           \
-    --test-args -Cpanic=abort                                                 \
-    --test-args --target-rustcflags                                           \
-    --test-args -Zpanic_abort_tests                                           \
+    --test-args -Clink-arg=--undefined-version                                \
     --test-args --remote-test-client                                          \
     --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
 )
@@ -736,7 +732,18 @@
 *Note: The test suite cannot be run in parallel at the moment, so `x.py`
 must be run with `--jobs 1` to ensure only one test runs at a time.*
 
-When finished, the test runner can be used to stop the test environment:
+By default, `x.py` compiles test binaries with `panic=unwind`. If you built your
+Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test
+binaries with `panic=abort` as well:
+
+```sh
+    --test-args --target-rustcflags                                           \
+    --test-args -Cpanic=abort                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Zpanic_abort_tests                                           \
+```
+
+When finished testing, the test runner can be used to stop the test environment:
 
 ```sh
 src/ci/docker/scripts/fuchsia-test-runner.py stop
@@ -764,8 +771,9 @@
 * `--symbol-path` gets required symbol paths, which are
 necessary for stepping through your program.
 
-The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can
-display Rust and/or Fuchsia source code in your debugging session.
+The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)"
+section describes how you can display Rust and/or Fuchsia source code in your
+debugging session.
 
 ### Using `zxdb`
 
@@ -866,6 +874,64 @@
  Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
  such as [fdio].
 
+### Debugging the compiler test suite
+
+Debugging the compiler test suite requires some special configuration:
+
+First, we have to properly configure zxdb so it will be able to find debug
+symbols and source information for our test. The test runner can do this for us
+with:
+
+```sh
+src/ci/docker/scripts/fuchsia-test-runner.py debug                            \
+    --rust-src ${RUST_SRC_PATH}                                               \
+    --fuchsia-src ${FUCHSIA_SRC_PATH}                                         \
+    --test ${TEST}
+```
+
+where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`).
+
+This will start a zxdb session that is properly configured for the specific test
+being run. All three arguments are optional, so you can omit `--fuchsia-src` if
+you don't have it downloaded. Now is a good time to set any desired breakpoints,
+like `b main`.
+
+Next, we have to tell `x.py` not to optimize or strip debug symbols from our
+test suite binaries. We can do this by passing some new arguments to `rustc`
+through our `x.py` invocation. The full invocation is:
+
+```sh
+( \
+    source config-env.sh &&                                                   \
+    ./x.py                                                                    \
+    --config config.toml                                                      \
+    --stage=2                                                                 \
+    test tests/${TEST}                                                        \
+    --target x86_64-unknown-fuchsia                                           \
+    --run=always --jobs 1                                                     \
+    --test-args --target-rustcflags                                           \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
+    --test-args --target-rustcflags                                           \
+    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
+    --test-args --target-rustcflags                                           \
+    --test-args -Clink-arg=--undefined-version                                \
+    --test-args --target-rustcflags                                           \
+    --test-args -Cdebuginfo=2                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Copt-level=0                                                 \
+    --test-args --target-rustcflags                                           \
+    --test-args -Cstrip=none                                                  \
+    --test-args --remote-test-client                                          \
+    --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
+)
+```
+
+*If you built your Rust toolchain with `panic=abort`, make sure to include the
+previous flags so your test binaries are also compiled with `panic=abort`.*
+
+Upon running this command, the test suite binary will be run and zxdb will
+attach and load any relevant debug symbols.
+
 [Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
 [Fuchsia]: https://fuchsia.dev/
 [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9ef0b50..89f1ad7 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -552,10 +552,7 @@
 }
 
 fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
-    matches!(
-        t,
-        Tag::Paragraph | Tag::Item | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote
-    )
+    matches!(t, Tag::Paragraph | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote)
 }
 
 fn is_forbidden_tag(t: &Tag<'_>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 1cdcccd..b8428d6 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -514,7 +514,7 @@
     }
 
     ParamEnv::new(
-        tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain(
+        tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
             params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
                 tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate {
                     trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]),
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 8ddbacc..0b0c6ad 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -173,7 +173,7 @@
         && let Some(iter_item) = cx.tcx
             .associated_items(iter_trait)
             .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
-        && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
+        && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
         && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
         && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 4e5af1c..df26b36 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -414,7 +414,7 @@
                             }
                         });
 
-                        let new_subst = cx.tcx.mk_substs(
+                        let new_subst = cx.tcx.mk_substs_from_iter(
                             call_substs.iter()
                                 .enumerate()
                                 .map(|(i, t)|
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 398329e..2fdd775 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -134,7 +134,7 @@
                 } else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
                     if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
                         cx.param_env,
-                        cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])),
+                        cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])),
                     ) {
                         if deref_ty == expr_ty {
                             let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 8b00ce2..bb8890d 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -237,7 +237,7 @@
         typeck_results,
         param_env: lcx.param_env,
         needed_resolution: false,
-        substs: lcx.tcx.intern_substs(&[]),
+        substs: ty::List::empty(),
     };
     cx.expr(e).map(|cst| (cst, cx.needed_resolution))
 }
@@ -306,7 +306,7 @@
         typeck_results,
         param_env: lcx.param_env,
         needed_resolution: false,
-        substs: lcx.tcx.intern_substs(&[]),
+        substs: ty::List::empty(),
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 34b9bb5..f8ec4bb 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -237,7 +237,7 @@
         kind: TypeVariableOriginKind::MiscVariable,
         span: DUMMY_SP,
     };
-    let ty_params = tcx.mk_substs(
+    let ty_params = tcx.mk_substs_from_iter(
         ty_params
             .into_iter()
             .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())),
@@ -1065,7 +1065,7 @@
         tcx,
         container_id,
         assoc_ty,
-        tcx.mk_substs(substs.into_iter().map(Into::into)),
+        tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)),
     )
 }
 
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 98eda97..373196b 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -22,7 +22,7 @@
         pub fn error_codes() -> Vec<(&'static str, Option<&'static str>)> {
             let mut errors: Vec<(&str, Option<&str>)> = vec![
                 $((stringify!($error_code), Some($message)),)+
-                $((stringify!($undocumented), None),)+
+                $((stringify!($undocumented), None),)*
             ];
             errors.sort();
             errors
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index ebb71b5..8443e90 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -363,7 +363,7 @@
                 tcx,
                 ty::ParamEnv::reveal_all(),
                 start_id,
-                tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]),
+                tcx.mk_substs(&[ty::subst::GenericArg::from(main_ret_ty)]),
             )
             .unwrap()
             .unwrap();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index c82c274..f21b4f8 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -173,7 +173,7 @@
 
             // let pointee = tcx.normalize_erasing_regions(param_env, pointee);
             // if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
-            //     return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
+            //     return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr)));
             // }
 
             let unsized_part = struct_tail_erasing_lifetimes(db, pointee.clone());
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index dd2fd19..8c904e8 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -31,7 +31,7 @@
 
 // Error codes that don't yet have a UI test. This list will eventually be removed.
 const IGNORE_UI_TEST_CHECK: &[&str] =
-    &["E0461", "E0465", "E0476", "E0514", "E0554", "E0640", "E0717", "E0729"];
+    &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"];
 
 macro_rules! verbose_print {
     ($verbose:expr, $($fmt:tt)*) => {
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir
deleted file mode 100644
index c2ea3ac..0000000
--- a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,70 +0,0 @@
-// MIR for `main` after ElaborateDrops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11
-    let _1: ();                          // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-    let mut _2: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-    let mut _3: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-    let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-    let mut _5: bool;                    // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    scope 1 {
-        debug x => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
-    }
-
-    bb0: {
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _5 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _2 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        StorageLive(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-        StorageLive(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-        _4 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
-        _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:8:23: 8:25
-                                         // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
-        _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:8:15: 8:20
-                                         // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
-    }
-
-    bb2: {
-        StorageDead(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        StorageDead(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-        _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2
-        return;                          // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2
-    }
-
-    bb3 (cleanup): {
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb4 (cleanup): {
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
-    }
-
-    bb5 (cleanup): {
-        goto -> bb8;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb6 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2
-    }
-
-    bb7 (cleanup): {
-        drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-
-    bb8 (cleanup): {
-        switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
-    }
-}
diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff
new file mode 100644
index 0000000..7ac75b5
--- /dev/null
+++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before ElaborateDrops
++ // MIR for `main` after ElaborateDrops
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11
+      let _1: ();                          // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+      let mut _2: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+      let mut _3: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+      let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
++     let mut _5: bool;                    // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
+      }
+  
+      bb0: {
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
++         _5 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          _2 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          StorageLive(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+          StorageLive(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+          _4 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+          _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:8:23: 8:25
+                                           // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_4);                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
+          _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:8:15: 8:20
+                                           // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_3);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         _5 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+          StorageDead(_2);                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+          _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2
+          return;                          // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2
+      }
+  
+      bb3 (cleanup): {
+-         drop(_3) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  
+      bb4 (cleanup): {
+-         drop(_4) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
+      }
+  
+      bb5 (cleanup): {
+-         drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++         goto -> bb8;                     // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  
+      bb6 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2
++     }
++ 
++     bb7 (cleanup): {
++         drop(_2) -> bb6;                 // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
++     }
++ 
++     bb8 (cleanup): {
++         switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs
index 638dc60..e1067ce 100644
--- a/tests/mir-opt/issue_41110.rs
+++ b/tests/mir-opt/issue_41110.rs
@@ -3,14 +3,14 @@
 // check that we don't emit multiple drop flags when they are not needed.
 
 
-// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir
+// EMIT_MIR issue_41110.main.ElaborateDrops.diff
 fn main() {
     let x = S.other(S.id());
 }
 
 // no_mangle to make sure this gets instantiated even in an executable.
 #[no_mangle]
-// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir
+// EMIT_MIR issue_41110.test.ElaborateDrops.diff
 pub fn test() {
     let u = S;
     let mut v = S;
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir
deleted file mode 100644
index 82989c3..0000000
--- a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,101 +0,0 @@
-// MIR for `test` after ElaborateDrops
-
-fn test() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15
-    let _1: S;                           // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-    let _3: ();                          // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12
-    let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11
-    let mut _5: S;                       // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10
-    let mut _6: bool;                    // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    scope 1 {
-        debug u => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
-        let mut _2: S;                   // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
-        scope 2 {
-            debug v => _2;               // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14
-        }
-    }
-
-    bb0: {
-        _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
-        _6 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        _1 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
-        StorageLive(_2);                 // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
-        _2 = S;                          // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18
-        StorageLive(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
-        StorageLive(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
-        _4 = move _2;                    // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
-        _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41110.rs:17:5: 17:9
-                                         // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        StorageDead(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
-        StorageDead(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13
-        StorageLive(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _6 = const false;                // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _5 = move _1;                    // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        goto -> bb12;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb2: {
-        goto -> bb3;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-    }
-
-    bb3: {
-        StorageDead(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-        _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2
-        drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb4: {
-        StorageDead(_2);                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-        goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb5: {
-        _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-        return;                          // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2
-    }
-
-    bb6 (cleanup): {
-        goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
-    }
-
-    bb7 (cleanup): {
-        goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
-    }
-
-    bb8 (cleanup): {
-        goto -> bb9;                     // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb9 (cleanup): {
-        goto -> bb14;                    // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb10 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2
-    }
-
-    bb11 (cleanup): {
-        _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-        goto -> bb6;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb12: {
-        _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-        goto -> bb2;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
-    }
-
-    bb13 (cleanup): {
-        drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-
-    bb14 (cleanup): {
-        switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
-    }
-}
diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff
new file mode 100644
index 0000000..79e3d07
--- /dev/null
+++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff
@@ -0,0 +1,109 @@
+- // MIR for `test` before ElaborateDrops
++ // MIR for `test` after ElaborateDrops
+  
+  fn test() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15
+      let _1: S;                           // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+      let _3: ();                          // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12
+      let mut _4: S;                       // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11
+      let mut _5: S;                       // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10
++     let mut _6: bool;                    // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      scope 1 {
+          debug u => _1;                   // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
+          let mut _2: S;                   // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
+          scope 2 {
+              debug v => _2;               // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14
+          }
+      }
+  
+      bb0: {
++         _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
++         _6 = const true;                 // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          _1 = S;                          // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
+          _2 = S;                          // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18
+          StorageLive(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
+          StorageLive(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+          _4 = move _2;                    // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+          _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41110.rs:17:5: 17:9
+                                           // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_4);                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
+          StorageDead(_3);                 // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13
+          StorageLive(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
++         _6 = const false;                // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+          _5 = move _1;                    // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+-         replace(_2 <- move _5) -> [return: bb2, unwind: bb6]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb12;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
+      }
+  
+      bb2: {
+-         drop(_5) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
++         goto -> bb3;                     // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+      }
+  
+      bb3: {
+          StorageDead(_5);                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+          _0 = const ();                   // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2
+          drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb4: {
+          StorageDead(_2);                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+-         drop(_1) -> bb5;                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb5;                     // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb5: {
++         _6 = const false;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2
+      }
+  
+      bb6 (cleanup): {
+          drop(_5) -> bb8;                 // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+      }
+  
+      bb7 (cleanup): {
+-         drop(_4) -> bb8;                 // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
++         goto -> bb8;                     // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
+      }
+  
+      bb8 (cleanup): {
+-         drop(_2) -> bb9;                 // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb9;                     // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb9 (cleanup): {
+-         drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++         goto -> bb14;                    // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  
+      bb10 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2
++     }
++ 
++     bb11 (cleanup): {
++         _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb10;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++     }
++ 
++     bb12: {
++         _2 = move _5;                    // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++         goto -> bb2;                     // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
++     }
++ 
++     bb13 (cleanup): {
++         drop(_1) -> bb10;                // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
++     }
++ 
++     bb14 (cleanup): {
++         switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir
deleted file mode 100644
index 0050427..0000000
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir
+++ /dev/null
@@ -1,152 +0,0 @@
-// MIR for `main` after ElaborateDrops
-
-fn main() -> () {
-    let mut _0: ();                      // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11
-    let _1: E;                           // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-    let mut _2: bool;                    // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14
-    let mut _3: E;                       // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20
-    let mut _4: K;                       // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19
-    let mut _5: isize;                   // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24
-    let mut _7: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _8: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _9: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _10: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    let mut _11: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    scope 1 {
-        debug e => _1;                   // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10
-        scope 2 {
-            debug _k => _6;              // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-            let _6: K;                   // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        }
-    }
-
-    bb0: {
-        _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        StorageLive(_1);                 // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
-        StorageLive(_2);                 // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-        _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-                                         // mir::Constant
-                                         // + span: $DIR/issue_41888.rs:8:8: 8:12
-                                         // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
-    }
-
-    bb1: {
-        switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
-    }
-
-    bb2: {
-        StorageLive(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
-        StorageLive(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
-        _4 = K;                          // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
-        _3 = E::F(move _4);              // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
-        StorageDead(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-        goto -> bb14;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb3: {
-        goto -> bb4;                     // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-    }
-
-    bb4: {
-        StorageDead(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-        _5 = discriminant(_1);           // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
-        switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
-    }
-
-    bb5: {
-        StorageLive(_6);                 // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _9 = const false;                // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _6 = move ((_1 as F).0: K);      // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
-        _0 = const ();                   // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10
-        StorageDead(_6);                 // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
-    }
-
-    bb6: {
-        _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
-    }
-
-    bb7: {
-        _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6
-        goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6
-    }
-
-    bb8: {
-        StorageDead(_2);                 // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6
-        goto -> bb20;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb9: {
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        StorageDead(_1);                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        return;                          // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2
-    }
-
-    bb10 (cleanup): {
-        goto -> bb11;                    // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
-    }
-
-    bb11 (cleanup): {
-        goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb12 (cleanup): {
-        resume;                          // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2
-    }
-
-    bb13 (cleanup): {
-        _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        goto -> bb10;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb14: {
-        _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-        goto -> bb3;                     // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
-    }
-
-    bb15: {
-        _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        goto -> bb9;                     // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb16 (cleanup): {
-        goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb17: {
-        drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb18 (cleanup): {
-        drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb19: {
-        _10 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb20: {
-        switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb21 (cleanup): {
-        _11 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-        switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-
-    bb22 (cleanup): {
-        switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
-    }
-}
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
new file mode 100644
index 0000000..257f0b1
--- /dev/null
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff
@@ -0,0 +1,158 @@
+- // MIR for `main` before ElaborateDrops
++ // MIR for `main` after ElaborateDrops
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11
+      let _1: E;                           // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+      let mut _2: bool;                    // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14
+      let mut _3: E;                       // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20
+      let mut _4: K;                       // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19
+      let mut _5: isize;                   // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24
++     let mut _7: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _8: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _9: bool;                    // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _10: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     let mut _11: isize;                  // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      scope 1 {
+          debug e => _1;                   // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10
+          scope 2 {
+              debug _k => _6;              // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+              let _6: K;                   // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          }
+      }
+  
+      bb0: {
++         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
++         _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+          StorageLive(_1);                 // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+          StorageLive(_2);                 // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+          _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+                                           // mir::Constant
+                                           // + span: $DIR/issue_41888.rs:8:8: 8:12
+                                           // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+      }
+  
+      bb2: {
+          StorageLive(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+          StorageLive(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+          _4 = K;                          // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+          _3 = E::F(move _4);              // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+          StorageDead(_4);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+-         replace(_1 <- move _3) -> [return: bb3, unwind: bb10]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb14;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+      }
+  
+      bb3: {
+-         drop(_3) -> [return: bb4, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
++         goto -> bb4;                     // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+      }
+  
+      bb4: {
+          StorageDead(_3);                 // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+          _5 = discriminant(_1);           // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
+          switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
+      }
+  
+      bb5: {
+          StorageLive(_6);                 // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
++         _9 = const false;                // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          _6 = move ((_1 as F).0: K);      // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+          _0 = const ();                   // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10
+          StorageDead(_6);                 // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
+      }
+  
+      bb6: {
+          _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
+      }
+  
+      bb7: {
+          _0 = const ();                   // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6
+          goto -> bb8;                     // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6
+      }
+  
+      bb8: {
+          StorageDead(_2);                 // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6
+-         drop(_1) -> bb9;                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb20;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  
+      bb9: {
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         _8 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         _9 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+          StorageDead(_1);                 // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+          return;                          // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2
+      }
+  
+      bb10 (cleanup): {
+          drop(_3) -> bb11;                // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+      }
+  
+      bb11 (cleanup): {
+-         drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  
+      bb12 (cleanup): {
+          resume;                          // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2
++     }
++ 
++     bb13 (cleanup): {
++         _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb12;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++     }
++ 
++     bb14: {
++         _7 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _8 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _9 = const true;                 // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         _1 = move _3;                    // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++         goto -> bb3;                     // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
++     }
++ 
++     bb15: {
++         _7 = const false;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         goto -> bb9;                     // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb16 (cleanup): {
++         goto -> bb12;                    // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb17: {
++         drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb18 (cleanup): {
++         drop(_1) -> bb12;                // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb19: {
++         _10 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb20: {
++         switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb21 (cleanup): {
++         _11 = discriminant(_1);          // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++         switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
++     }
++ 
++     bb22 (cleanup): {
++         switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+      }
+  }
+  
diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs
index c1046c1..0f10c0a 100644
--- a/tests/mir-opt/issue_41888.rs
+++ b/tests/mir-opt/issue_41888.rs
@@ -2,7 +2,7 @@
 // check that we clear the "ADT master drop flag" even when there are
 // no fields to be dropped.
 
-// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir
+// EMIT_MIR issue_41888.main.ElaborateDrops.diff
 fn main() {
     let e;
     if cond() {
diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml
index 5f4c1ba..6e2321a 100644
--- a/tests/rustdoc-gui/help-page.goml
+++ b/tests/rustdoc-gui/help-page.goml
@@ -68,5 +68,4 @@
 assert-false: "#help"
 click: "#help-button > a"
 click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']"
-wait-for: 2000
-assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"}
+wait-for-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"}
diff --git a/tests/rustdoc-ui/auxiliary/panic-handler.rs b/tests/rustdoc-ui/auxiliary/panic-handler.rs
new file mode 100644
index 0000000..0aaaeee
--- /dev/null
+++ b/tests/rustdoc-ui/auxiliary/panic-handler.rs
@@ -0,0 +1,9 @@
+// compile-flags: -C panic=abort
+
+#![no_std]
+#![no_main]
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/rustdoc-ui/issue-107918.rs b/tests/rustdoc-ui/issue-107918.rs
new file mode 100644
index 0000000..13788df
--- /dev/null
+++ b/tests/rustdoc-ui/issue-107918.rs
@@ -0,0 +1,12 @@
+// aux-build:panic-handler.rs
+// compile-flags: --document-private-items
+// build-pass
+// ignore-windows
+
+#![no_std]
+#![no_main]
+
+#[panic_handler]
+fn panic(_: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr
index a16b5b6..72f35cb 100644
--- a/tests/rustdoc-ui/unable-fulfill-trait.stderr
+++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unable-fulfill-trait.rs:4:17
    |
 LL |     field1: dyn Bar<'a, 'b,>,
diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc/item-desc-list-at-start.item-table.html
new file mode 100644
index 0000000..72bde57
--- /dev/null
+++ b/tests/rustdoc/item-desc-list-at-start.item-table.html
@@ -0,0 +1 @@
+<ul class="item-table"><li><div class="item-name"><a class="constant" href="constant.MY_CONSTANT.html" title="constant item_desc_list_at_start::MY_CONSTANT">MY_CONSTANT</a></div><div class="desc docblock-short">Groups: <code>SamplePatternSGIS</code>, <code>SamplePatternEXT</code></div></li></ul>
\ No newline at end of file
diff --git a/tests/rustdoc/item-desc-list-at-start.rs b/tests/rustdoc/item-desc-list-at-start.rs
new file mode 100644
index 0000000..d88c61d
--- /dev/null
+++ b/tests/rustdoc/item-desc-list-at-start.rs
@@ -0,0 +1,9 @@
+// @has item_desc_list_at_start/index.html
+// @count - '//ul[@class="item-table"]/li/div/li' 0
+// @count - '//ul[@class="item-table"]/li' 1
+// @snapshot item-table - '//ul[@class="item-table"]'
+
+// based on https://docs.rs/gl_constants/0.1.1/src/gl_constants/lib.rs.html#16
+
+/// * Groups: `SamplePatternSGIS`, `SamplePatternEXT`
+pub const MY_CONSTANT: usize = 0;
diff --git a/tests/ui-fulldeps/create-dir-all-bare.rs b/tests/ui-fulldeps/create-dir-all-bare.rs
deleted file mode 100644
index 4554680..0000000
--- a/tests/ui-fulldeps/create-dir-all-bare.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-fn main() {
-    let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
-    env::set_current_dir(&path).unwrap();
-    fs::create_dir_all("create-dir-all-bare").unwrap();
-}
diff --git a/tests/ui-fulldeps/rename-directory.rs b/tests/ui-fulldeps/rename-directory.rs
deleted file mode 100644
index 8fc340c..0000000
--- a/tests/ui-fulldeps/rename-directory.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// run-pass
-
-#![allow(unused_must_use)]
-#![allow(unused_imports)]
-// This test can't be a unit test in std,
-// because it needs TempDir, which is in extra
-
-// ignore-cross-compile
-
-use std::env;
-use std::ffi::CString;
-use std::fs::{self, File};
-use std::path::PathBuf;
-
-fn rename_directory() {
-    let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap());
-    let old_path = tmpdir.join("foo/bar/baz");
-    fs::create_dir_all(&old_path).unwrap();
-    let test_file = &old_path.join("temp.txt");
-
-    File::create(test_file).unwrap();
-
-    let new_path = tmpdir.join("quux/blat");
-    fs::create_dir_all(&new_path).unwrap();
-    fs::rename(&old_path, &new_path.join("newdir"));
-    assert!(new_path.join("newdir").is_dir());
-    assert!(new_path.join("newdir/temp.txt").exists());
-}
-
-pub fn main() { rename_directory() }
diff --git a/tests/ui-fulldeps/issue-15149.rs b/tests/ui-fulldeps/std/issue-15149.rs
similarity index 100%
rename from tests/ui-fulldeps/issue-15149.rs
rename to tests/ui-fulldeps/std/issue-15149.rs
diff --git a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs
similarity index 100%
rename from tests/ui-fulldeps/issue-81357-unsound-file-methods.rs
rename to tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs
diff --git a/tests/ui-fulldeps/stdio-from.rs b/tests/ui-fulldeps/std/stdio-from.rs
similarity index 100%
rename from tests/ui-fulldeps/stdio-from.rs
rename to tests/ui-fulldeps/std/stdio-from.rs
diff --git a/tests/ui-fulldeps/switch-stdout.rs b/tests/ui-fulldeps/std/switch-stdout.rs
similarity index 100%
rename from tests/ui-fulldeps/switch-stdout.rs
rename to tests/ui-fulldeps/std/switch-stdout.rs
diff --git a/tests/ui/argument-suggestions/issue-100154.stderr b/tests/ui/argument-suggestions/issue-100154.stderr
index 1499229..2504f61 100644
--- a/tests/ui/argument-suggestions/issue-100154.stderr
+++ b/tests/ui/argument-suggestions/issue-100154.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-100154.rs:4:5
    |
 LL |     foo::<()>(());
diff --git a/tests/ui/async-await/issues/issue-65159.rs b/tests/ui/async-await/issues/issue-65159.rs
index df2ca02..6e54750 100644
--- a/tests/ui/async-await/issues/issue-65159.rs
+++ b/tests/ui/async-await/issues/issue-65159.rs
@@ -3,7 +3,7 @@
 // edition:2018
 
 async fn copy() -> Result<()>
-//~^ ERROR this enum takes 2 generic arguments
+//~^ ERROR enum takes 2 generic arguments
 {
     Ok(())
 }
diff --git a/tests/ui/async-await/issues/issue-65159.stderr b/tests/ui/async-await/issues/issue-65159.stderr
index 40c0e72..b874133 100644
--- a/tests/ui/async-await/issues/issue-65159.stderr
+++ b/tests/ui/async-await/issues/issue-65159.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-65159.rs:5:20
    |
 LL | async fn copy() -> Result<()>
diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
index dd0320b..d067ff4 100644
--- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
+++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
@@ -14,8 +14,8 @@
 }
 
 async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
-    //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^^ ERROR struct takes 1 generic argument but 0 generic arguments were supplied
     LockedMarket(generator.lock().unwrap().buy())
 }
 
diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
index d2b927f..73e0aaf 100644
--- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
+++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59
    |
 LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
@@ -12,7 +12,7 @@
 LL | struct LockedMarket<T>(T);
    |        ^^^^^^^^^^^^
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59
    |
 LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
index 7aea0d3..18a9b53 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs
@@ -7,8 +7,8 @@
 
 const _: () = {
     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
-    //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
-    //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+    //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+    //~| ERROR associated type takes 0 generic arguments but 1 generic argument
 };
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
index 8278eda..175d54e 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/issue-102768.rs:9:30
    |
 LL |     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
@@ -14,7 +14,7 @@
 LL |     fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
    |                                +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-102768.rs:9:30
    |
 LL |     fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
index c587a7e..302da59 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-76595.rs:15:5
    |
 LL |     test::<2>();
diff --git a/tests/ui/const-generics/incorrect-number-of-const-args.stderr b/tests/ui/const-generics/incorrect-number-of-const-args.stderr
index a845454..01ac4e6 100644
--- a/tests/ui/const-generics/incorrect-number-of-const-args.stderr
+++ b/tests/ui/const-generics/incorrect-number-of-const-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/incorrect-number-of-const-args.rs:6:5
    |
 LL |     foo::<0>();
@@ -16,7 +16,7 @@
 LL |     foo::<0, Y>();
    |            +++
 
-error[E0107]: this function takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: function takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/incorrect-number-of-const-args.rs:9:5
    |
 LL |     foo::<0, 0, 0>();
diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
index cdc54b2..bf10f47 100644
--- a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
+++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs
@@ -4,11 +4,11 @@
 
 fn main() {
     let _: u32 = 5i32.try_into::<32>().unwrap();
-    //~^ ERROR this method takes
+    //~^ ERROR method takes
 
     S.f::<0>();
     //~^ ERROR no method named `f`
 
     S::<0>;
-    //~^ ERROR this struct takes 0
+    //~^ ERROR struct takes 0
 }
diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
index a9754bc..4a649d8 100644
--- a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
+++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/invalid-const-arg-for-type-param.rs:6:23
    |
 LL |     let _: u32 = 5i32.try_into::<32>().unwrap();
@@ -23,7 +23,7 @@
 LL |     S.f::<0>();
    |       ^ method not found in `S`
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/invalid-const-arg-for-type-param.rs:12:5
    |
 LL |     S::<0>;
diff --git a/tests/ui/const-generics/invalid-constant-in-args.rs b/tests/ui/const-generics/invalid-constant-in-args.rs
index 7419d4a..fd25919 100644
--- a/tests/ui/const-generics/invalid-constant-in-args.rs
+++ b/tests/ui/const-generics/invalid-constant-in-args.rs
@@ -2,5 +2,5 @@
 
 fn main() {
     let _: Cell<&str, "a"> = Cell::new("");
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/const-generics/invalid-constant-in-args.stderr b/tests/ui/const-generics/invalid-constant-in-args.stderr
index 993b635..2545cc6 100644
--- a/tests/ui/const-generics/invalid-constant-in-args.stderr
+++ b/tests/ui/const-generics/invalid-constant-in-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/invalid-constant-in-args.rs:4:12
    |
 LL |     let _: Cell<&str, "a"> = Cell::new("");
diff --git a/tests/ui/const-generics/issues/issue-87493.rs b/tests/ui/const-generics/issues/issue-87493.rs
index d8599ab..80472e6 100644
--- a/tests/ui/const-generics/issues/issue-87493.rs
+++ b/tests/ui/const-generics/issues/issue-87493.rs
@@ -7,7 +7,7 @@
     S: MyTrait,
     T: MyTrait<Assoc == S::Assoc>,
     //~^ ERROR: expected one of `,` or `>`, found `==`
-    //~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
 {
 }
 
diff --git a/tests/ui/const-generics/issues/issue-87493.stderr b/tests/ui/const-generics/issues/issue-87493.stderr
index 653afae..73bd6ed 100644
--- a/tests/ui/const-generics/issues/issue-87493.stderr
+++ b/tests/ui/const-generics/issues/issue-87493.stderr
@@ -9,7 +9,7 @@
 LL |     T: MyTrait<Assoc = S::Assoc>,
    |                      ~
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-87493.rs:8:8
    |
 LL |     T: MyTrait<Assoc == S::Assoc>,
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
index b126b24..79743ab 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs
@@ -7,7 +7,7 @@
 const T: usize = 42;
 
 impl Foo<N = 3> for Bar {
-//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
+//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
 //~| ERROR associated type bindings are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
index acfdde8..4f4e1aa 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr
@@ -7,7 +7,7 @@
    = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-89013-no-kw.rs:9:6
    |
 LL | impl Foo<N = 3> for Bar {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
index 9431779..335d0d9 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs
@@ -8,7 +8,7 @@
 
 impl Foo<N = const 3> for Bar {
 //~^ ERROR expected lifetime, type, or constant, found keyword `const`
-//~| ERROR this trait takes 1 generic
+//~| ERROR trait takes 1 generic
 //~| ERROR associated type bindings are not allowed here
 //~| ERROR associated const equality is incomplete
     fn do_x(&self) -> [u8; 3] {
diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
index 583749a..3d2b98f 100644
--- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
+++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr
@@ -19,7 +19,7 @@
    = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
    = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/issue-89013.rs:9:6
    |
 LL | impl Foo<N = const 3> for Bar {
diff --git a/tests/ui/constructor-lifetime-args.rs b/tests/ui/constructor-lifetime-args.rs
index a824a44..f5802e7 100644
--- a/tests/ui/constructor-lifetime-args.rs
+++ b/tests/ui/constructor-lifetime-args.rs
@@ -15,12 +15,12 @@
 fn main() {
     S(&0, &0); // OK
     S::<'static>(&0, &0);
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     S::<'static, 'static, 'static>(&0, &0);
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     E::V(&0); // OK
     E::V::<'static>(&0);
-    //~^ ERROR this enum takes 2 lifetime arguments
+    //~^ ERROR enum takes 2 lifetime arguments
     E::V::<'static, 'static, 'static>(&0);
-    //~^ ERROR this enum takes 2 lifetime arguments
+    //~^ ERROR enum takes 2 lifetime arguments
 }
diff --git a/tests/ui/constructor-lifetime-args.stderr b/tests/ui/constructor-lifetime-args.stderr
index bc1141b..a18123f 100644
--- a/tests/ui/constructor-lifetime-args.stderr
+++ b/tests/ui/constructor-lifetime-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/constructor-lifetime-args.rs:17:5
    |
 LL |     S::<'static>(&0, &0);
@@ -16,7 +16,7 @@
 LL |     S::<'static, 'static>(&0, &0);
    |                +++++++++
 
-error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/constructor-lifetime-args.rs:19:5
    |
 LL |     S::<'static, 'static, 'static>(&0, &0);
@@ -30,7 +30,7 @@
 LL | struct S<'a, 'b>(&'a u8, &'b u8);
    |        ^ --  --
 
-error[E0107]: this enum takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/constructor-lifetime-args.rs:22:8
    |
 LL |     E::V::<'static>(&0);
@@ -48,7 +48,7 @@
 LL |     E::V::<'static, 'static>(&0);
    |                   +++++++++
 
-error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/constructor-lifetime-args.rs:24:8
    |
 LL |     E::V::<'static, 'static, 'static>(&0);
diff --git a/tests/ui/consts/gate-do-not-const-check.rs b/tests/ui/consts/gate-do-not-const-check.rs
new file mode 100644
index 0000000..be7e70d
--- /dev/null
+++ b/tests/ui/consts/gate-do-not-const-check.rs
@@ -0,0 +1,5 @@
+#[rustc_do_not_const_check]
+//~^ ERROR this is an internal attribute that will never be stable
+const fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/consts/gate-do-not-const-check.stderr b/tests/ui/consts/gate-do-not-const-check.stderr
new file mode 100644
index 0000000..3bb1360
--- /dev/null
+++ b/tests/ui/consts/gate-do-not-const-check.stderr
@@ -0,0 +1,11 @@
+error[E0658]: this is an internal attribute that will never be stable
+  --> $DIR/gate-do-not-const-check.rs:1:1
+   |
+LL | #[rustc_do_not_const_check]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/error-codes/E0107.rs b/tests/ui/error-codes/E0107.rs
index d369fc2..fd23e7c 100644
--- a/tests/ui/error-codes/E0107.rs
+++ b/tests/ui/error-codes/E0107.rs
@@ -11,39 +11,39 @@
 
 struct Baz<'a, 'b, 'c> {
     buzz: Buzz<'a>,
-    //~^ ERROR this struct takes 2 lifetime arguments
+    //~^ ERROR struct takes 2 lifetime arguments
     //~| HELP add missing lifetime argument
 
     bar: Bar<'a>,
-    //~^ ERROR this enum takes 0 lifetime arguments
+    //~^ ERROR enum takes 0 lifetime arguments
     //~| HELP remove these generics
 
     foo2: Foo<'a, 'b, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux1: Qux<'a, 'b, i32>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     qux2: Qux<'a, i32, 'b>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     qux3: Qux<'a, 'b, 'c, i32>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux4: Qux<'a, i32, 'b, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove these lifetime arguments
 
     qux5: Qux<'a, 'b, i32, 'c>,
-    //~^ ERROR this struct takes 1 lifetime argument
+    //~^ ERROR struct takes 1 lifetime argument
     //~| HELP remove this lifetime argument
 
     quux: Quux<'a, i32, 'b>,
-    //~^ ERROR this struct takes 0 lifetime arguments
+    //~^ ERROR struct takes 0 lifetime arguments
     //~| HELP remove this lifetime argument
 }
 
@@ -53,7 +53,7 @@
 }
 
 fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
-    //~^ ERROR this trait takes 0 generic arguments
+    //~^ ERROR trait takes 0 generic arguments
     //~| HELP replace the generic bounds with the associated types
 }
 
diff --git a/tests/ui/error-codes/E0107.stderr b/tests/ui/error-codes/E0107.stderr
index 03430f8..3f540eb 100644
--- a/tests/ui/error-codes/E0107.stderr
+++ b/tests/ui/error-codes/E0107.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/E0107.rs:13:11
    |
 LL |     buzz: Buzz<'a>,
@@ -16,7 +16,7 @@
 LL |     buzz: Buzz<'a, 'a>,
    |                  ++++
 
-error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/E0107.rs:17:10
    |
 LL |     bar: Bar<'a>,
@@ -30,7 +30,7 @@
 LL | enum Bar {
    |      ^^^
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:21:11
    |
 LL |     foo2: Foo<'a, 'b, 'c>,
@@ -44,7 +44,7 @@
 LL | struct Foo<'a>(&'a str);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:25:11
    |
 LL |     qux1: Qux<'a, 'b, i32>,
@@ -58,7 +58,7 @@
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:29:11
    |
 LL |     qux2: Qux<'a, i32, 'b>,
@@ -72,7 +72,7 @@
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:33:11
    |
 LL |     qux3: Qux<'a, 'b, 'c, i32>,
@@ -86,7 +86,7 @@
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:37:11
    |
 LL |     qux4: Qux<'a, i32, 'b, 'c>,
@@ -100,7 +100,7 @@
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied
   --> $DIR/E0107.rs:41:11
    |
 LL |     qux5: Qux<'a, 'b, i32, 'c>,
@@ -114,7 +114,7 @@
 LL | struct Qux<'a, T>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 0 lifetime arguments but 2 lifetime arguments were supplied
+error[E0107]: struct takes 0 lifetime arguments but 2 lifetime arguments were supplied
   --> $DIR/E0107.rs:45:11
    |
 LL |     quux: Quux<'a, i32, 'b>,
@@ -128,7 +128,7 @@
 LL | struct Quux<T>(T);
    |        ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: trait takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/E0107.rs:55:27
    |
 LL | fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs
new file mode 100644
index 0000000..d5e4b8d
--- /dev/null
+++ b/tests/ui/error-codes/E0476.rs
@@ -0,0 +1,13 @@
+#![feature(coerce_unsized)]
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::CoerceUnsized;
+
+struct Wrapper<T>(T);
+
+impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+//~^ ERROR lifetime of the source pointer does not outlive lifetime bound of the object type [E0476]
+//~^^ ERROR E0119
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0476.stderr b/tests/ui/error-codes/E0476.stderr
new file mode 100644
index 0000000..a4bb265
--- /dev/null
+++ b/tests/ui/error-codes/E0476.stderr
@@ -0,0 +1,31 @@
+error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>`
+  --> $DIR/E0476.rs:9:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T
+             where 'b: 'a, T: Unsize<U>, T: ?Sized, U: ?Sized;
+
+error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type
+  --> $DIR/E0476.rs:9:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: object type is valid for the lifetime `'a` as defined here
+  --> $DIR/E0476.rs:9:6
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |      ^^
+note: source pointer is only valid for the lifetime `'b` as defined here
+  --> $DIR/E0476.rs:9:10
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |          ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0476.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
index c50b9a1..a7a9db7 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed
@@ -4,16 +4,23 @@
 // If this recovery happens, then plenty of errors are emitted. Here, we expect
 // only one error.
 //
-// This is part of issue #88065:
+// This is part of the following issues:
 // https://github.com/rust-lang/rust/issues/88065
+// https://github.com/rust-lang/rust/issues/107959
 
 // run-rustfix
 
 fn main() {
+    // Closure with multiple expressions delimited by semicolon.
     let num = 5;
     (1..num).reduce(|a, b| {
         //~^ ERROR: closure bodies that contain statements must be surrounded by braces
         println!("{}", a);
         a * b
     }).unwrap();
+
+    // Closure with a single expression ended by a semicolon.
+    let mut v = vec![1, 2, 3];
+    v.iter_mut().for_each(|x| {*x = *x+1;});
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
 }
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
index 58c81f3..b5690b2 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs
@@ -4,16 +4,23 @@
 // If this recovery happens, then plenty of errors are emitted. Here, we expect
 // only one error.
 //
-// This is part of issue #88065:
+// This is part of the following issues:
 // https://github.com/rust-lang/rust/issues/88065
+// https://github.com/rust-lang/rust/issues/107959
 
 // run-rustfix
 
 fn main() {
+    // Closure with multiple expressions delimited by semicolon.
     let num = 5;
     (1..num).reduce(|a, b|
         //~^ ERROR: closure bodies that contain statements must be surrounded by braces
         println!("{}", a);
         a * b
     ).unwrap();
+
+    // Closure with a single expression ended by a semicolon.
+    let mut v = vec![1, 2, 3];
+    v.iter_mut().for_each(|x|*x = *x+1;);
+        //~^ ERROR: closure bodies that contain statements must be surrounded by braces
 }
diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
index dac9a8c..039eef9 100644
--- a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
+++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr
@@ -1,5 +1,5 @@
 error: closure bodies that contain statements must be surrounded by braces
-  --> $DIR/missing_braces_around_block.rs:14:26
+  --> $DIR/missing_braces_around_block.rs:16:26
    |
 LL |     (1..num).reduce(|a, b|
    |                          ^
@@ -8,14 +8,14 @@
    |     ^
    |
 note: statement found outside of a block
-  --> $DIR/missing_braces_around_block.rs:16:26
+  --> $DIR/missing_braces_around_block.rs:18:26
    |
 LL |         println!("{}", a);
    |         -----------------^ this `;` turns the preceding closure into a statement
    |         |
    |         this expression is a statement because of the trailing semicolon
 note: the closure body may be incorrectly delimited
-  --> $DIR/missing_braces_around_block.rs:14:21
+  --> $DIR/missing_braces_around_block.rs:16:21
    |
 LL |       (1..num).reduce(|a, b|
    |  _____________________^
@@ -34,5 +34,30 @@
 LL ~     }).unwrap();
    |
 
-error: aborting due to previous error
+error: closure bodies that contain statements must be surrounded by braces
+  --> $DIR/missing_braces_around_block.rs:24:29
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                             ^          ^
+   |
+note: statement found outside of a block
+  --> $DIR/missing_braces_around_block.rs:24:39
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                              ---------^ this `;` turns the preceding closure into a statement
+   |                              |
+   |                              this expression is a statement because of the trailing semicolon
+note: the closure body may be incorrectly delimited
+  --> $DIR/missing_braces_around_block.rs:24:27
+   |
+LL |     v.iter_mut().for_each(|x|*x = *x+1;);
+   |                           ^^^^^^^^^^^^ - ...but likely you meant the closure to end here
+   |                           |
+   |                           this is the parsed closure...
+help: try adding braces
+   |
+LL |     v.iter_mut().for_each(|x| {*x = *x+1;});
+   |                               +          +
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
index 9eb0696..5738dfa 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -5,12 +5,12 @@
 fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
   //~^ ERROR: lifetime in trait object type must be followed by `+`
   //~| ERROR: parenthesized generic arguments cannot be used
-  //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
-  //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+  //~| ERROR associated type takes 0 generic arguments but 1 generic argument
+  //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
 
 
 fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
   //~^ ERROR: parenthesized generic arguments cannot be used
-  //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+  //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index 1657797..4618533 100644
--- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -23,7 +23,7 @@
    |                            |
    |                            help: remove these parentheses
 
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
    |
 LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
@@ -39,7 +39,7 @@
 LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {}
    |                             +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
    |
 LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
@@ -53,7 +53,7 @@
 LL |   type Y<'a>;
    |        ^
 
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
    |
 LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs
index 78def80..331511b 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.rs
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs
@@ -12,9 +12,9 @@
 //~^ ERROR missing generics for associated type
 
 fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
-//~^ ERROR this struct takes 3 lifetime arguments but 2 lifetime
+//~^ ERROR struct takes 3 lifetime arguments but 2 lifetime
 
 fn f<'a>(_arg: Foo<'a>) {}
-//~^ ERROR this struct takes 3 lifetime arguments but 1 lifetime
+//~^ ERROR struct takes 3 lifetime arguments but 1 lifetime
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
index 8f74b12..1a7a2e7 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -14,7 +14,7 @@
 LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
    |                                 ++++++++
 
-error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
   --> $DIR/missing_lifetime_args.rs:14:26
    |
 LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
@@ -32,7 +32,7 @@
 LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
    |                                    ++++
 
-error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing_lifetime_args.rs:17:16
    |
 LL | fn f<'a>(_arg: Foo<'a>) {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.rs b/tests/ui/generic-associated-types/missing_lifetime_const.rs
index 8b174b9e..6e395df 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_const.rs
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.rs
@@ -4,7 +4,7 @@
 
 fn foo<T: Foo>() {
     let _: <T as Foo>::Assoc<3>;
-      //~^ ERROR  this associated type
+      //~^ ERROR  associated type
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.stderr b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
index 62d2e9f..41945aa 100644
--- a/tests/ui/generic-associated-types/missing_lifetime_const.stderr
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/missing_lifetime_const.rs:6:24
    |
 LL |     let _: <T as Foo>::Assoc<3>;
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.rs b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
index 8428e77..ae2f7c0 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind.rs
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
@@ -9,10 +9,10 @@
     // Test parameters in default values
     type FOk<T> = Self::E<'static, T>;
     type FErr1 = Self::E<'static, 'static>;
-    //~^ ERROR this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this associated type takes 1
+    //~^ ERROR associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR associated type takes 1
     type FErr2<T> = Self::E<'static, T, u32>;
-    //~^ ERROR this associated type takes 1
+    //~^ ERROR associated type takes 1
 }
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
index c20b966..4523044 100644
--- a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:11:24
    |
 LL |     type FErr1 = Self::E<'static, 'static>;
@@ -12,7 +12,7 @@
 LL |     type E<'a, T>;
    |          ^ --
 
-error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: associated type takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:11:24
    |
 LL |     type FErr1 = Self::E<'static, 'static>;
@@ -28,7 +28,7 @@
 LL |     type FErr1 = Self::E<'static, 'static, T>;
    |                                          +++
 
-error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated type takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/parameter_number_and_kind.rs:14:27
    |
 LL |     type FErr2<T> = Self::E<'static, T, u32>;
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
index 1622b92a..c58f9cf 100644
--- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
@@ -4,8 +4,8 @@
 
 const _: () = {
   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
-      //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
-      //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+      //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
+      //~| ERROR associated type takes 0 generic arguments but 1 generic argument
 };
 
 fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
index 0a09ec5..fab5b47 100644
--- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/trait-path-type-error-once-implemented.rs:6:29
    |
 LL |   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
@@ -14,7 +14,7 @@
 LL |   fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
    |                               +++
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/trait-path-type-error-once-implemented.rs:6:29
    |
 LL |   fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
diff --git a/tests/ui/generics/bad-mid-path-type-params.rs b/tests/ui/generics/bad-mid-path-type-params.rs
index 23a5d15..37d484c 100644
--- a/tests/ui/generics/bad-mid-path-type-params.rs
+++ b/tests/ui/generics/bad-mid-path-type-params.rs
@@ -28,17 +28,17 @@
 
 fn foo<'a>() {
     let _ = S::new::<isize,f64>(1, 1.0);
-    //~^ ERROR this associated function takes 1
+    //~^ ERROR associated function takes 1
 
     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
 
     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
-    //~^ ERROR this associated function takes 1
+    //~^ ERROR associated function takes 1
 
     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
-    //~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this associated function takes 1
+    //~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR associated function takes 1
 }
 
 fn main() {}
diff --git a/tests/ui/generics/bad-mid-path-type-params.stderr b/tests/ui/generics/bad-mid-path-type-params.stderr
index aee2b60..71e15dd 100644
--- a/tests/ui/generics/bad-mid-path-type-params.stderr
+++ b/tests/ui/generics/bad-mid-path-type-params.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:30:16
    |
 LL |     let _ = S::new::<isize,f64>(1, 1.0);
@@ -12,7 +12,7 @@
 LL |     fn new<U>(x: T, _: U) -> S<T> {
    |        ^^^ -
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/bad-mid-path-type-params.rs:33:13
    |
 LL |     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
@@ -26,7 +26,7 @@
 LL | struct S<T> {
    |        ^
 
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:36:24
    |
 LL |     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
@@ -40,7 +40,7 @@
 LL |     fn new<U>(x: T, y: U) -> Self;
    |        ^^^ -
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/bad-mid-path-type-params.rs:39:17
    |
 LL |     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
@@ -54,7 +54,7 @@
 LL | trait Trait<T> {
    |       ^^^^^
 
-error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/bad-mid-path-type-params.rs:39:36
    |
 LL |     let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
diff --git a/tests/ui/generics/generic-arg-mismatch-recover.rs b/tests/ui/generics/generic-arg-mismatch-recover.rs
index 2cf7f1d..947f334 100644
--- a/tests/ui/generics/generic-arg-mismatch-recover.rs
+++ b/tests/ui/generics/generic-arg-mismatch-recover.rs
@@ -4,9 +4,9 @@
 
 fn main() {
     Foo::<'static, 'static, ()>(&0);
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
 
     Bar::<'static, 'static, ()>(&());
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this struct takes 0
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR struct takes 0
 }
diff --git a/tests/ui/generics/generic-arg-mismatch-recover.stderr b/tests/ui/generics/generic-arg-mismatch-recover.stderr
index 45fea92..f549a71 100644
--- a/tests/ui/generics/generic-arg-mismatch-recover.stderr
+++ b/tests/ui/generics/generic-arg-mismatch-recover.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/generic-arg-mismatch-recover.rs:6:5
    |
 LL |     Foo::<'static, 'static, ()>(&0);
@@ -12,7 +12,7 @@
 LL | struct Foo<'a, T: 'a>(&'a T);
    |        ^^^ --
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/generic-arg-mismatch-recover.rs:9:5
    |
 LL |     Bar::<'static, 'static, ()>(&());
@@ -26,7 +26,7 @@
 LL | struct Bar<'a>(&'a ());
    |        ^^^ --
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/generic-arg-mismatch-recover.rs:9:5
    |
 LL |     Bar::<'static, 'static, ()>(&());
diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.rs b/tests/ui/generics/generic-impl-less-params-with-defaults.rs
index 66afbb5..6c00411 100644
--- a/tests/ui/generics/generic-impl-less-params-with-defaults.rs
+++ b/tests/ui/generics/generic-impl-less-params-with-defaults.rs
@@ -9,5 +9,5 @@
 
 fn main() {
     Foo::<isize>::new();
-    //~^ ERROR this struct takes at least 2 generic arguments but 1 generic argument
+    //~^ ERROR struct takes at least 2 generic arguments but 1 generic argument
 }
diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
index cdbb579..262561f 100644
--- a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/generic-impl-less-params-with-defaults.rs:11:5
    |
 LL |     Foo::<isize>::new();
diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.rs b/tests/ui/generics/generic-impl-more-params-with-defaults.rs
index a283323..be633ec 100644
--- a/tests/ui/generics/generic-impl-more-params-with-defaults.rs
+++ b/tests/ui/generics/generic-impl-more-params-with-defaults.rs
@@ -11,5 +11,5 @@
 
 fn main() {
     Vec::<isize, Heap, bool>::new();
-    //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+    //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments were supplied
 }
diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
index fe9b670..2f4682c 100644
--- a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/generic-impl-more-params-with-defaults.rs:13:5
    |
 LL |     Vec::<isize, Heap, bool>::new();
diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.rs b/tests/ui/generics/generic-type-more-params-with-defaults.rs
index 3dab032..b83fdb5 100644
--- a/tests/ui/generics/generic-type-more-params-with-defaults.rs
+++ b/tests/ui/generics/generic-type-more-params-with-defaults.rs
@@ -7,5 +7,5 @@
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
-    //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments
+    //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments
 }
diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.stderr b/tests/ui/generics/generic-type-more-params-with-defaults.stderr
index 7f0198f..4d01ba1 100644
--- a/tests/ui/generics/generic-type-more-params-with-defaults.stderr
+++ b/tests/ui/generics/generic-type-more-params-with-defaults.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/generic-type-more-params-with-defaults.rs:9:12
    |
 LL |     let _: Vec<isize, Heap, bool>;
diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs
index cd2f96a..e4eaff2 100644
--- a/tests/ui/generics/wrong-number-of-args.rs
+++ b/tests/ui/generics/wrong-number-of-args.rs
@@ -4,18 +4,18 @@
     type A = Ty;
 
     type B = Ty<'static>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
     //~| HELP remove these generics
 
     type C = Ty<'static, usize>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
-    //~| ERROR this struct takes 0 generic arguments but 1 generic argument
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
+    //~| ERROR struct takes 0 generic arguments but 1 generic argument
     //~| HELP remove this lifetime argument
     //~| HELP remove this generic argument
 
     type D = Ty<'static, usize, { 0 }>;
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
-    //~| ERROR this struct takes 0 generic arguments but 2 generic arguments
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
+    //~| ERROR struct takes 0 generic arguments but 2 generic arguments
     //~| HELP remove this lifetime argument
     //~| HELP remove these generic arguments
 }
@@ -28,17 +28,17 @@
     //~| HELP add missing
 
     type B = Ty<usize>;
-    //~^ ERROR this struct takes 2 generic arguments but 1 generic argument
+    //~^ ERROR struct takes 2 generic arguments but 1 generic argument
     //~| HELP add missing
 
     type C = Ty<usize, String>;
 
     type D = Ty<usize, String, char>;
-    //~^ ERROR this struct takes 2 generic arguments but 3 generic arguments
+    //~^ ERROR struct takes 2 generic arguments but 3 generic arguments
     //~| HELP remove this
 
     type E = Ty<>;
-    //~^ ERROR this struct takes 2 generic arguments but 0 generic arguments were supplied
+    //~^ ERROR struct takes 2 generic arguments but 0 generic arguments were supplied
     //~| HELP add missing
 }
 
@@ -52,7 +52,7 @@
     //~| HELP consider introducing
 
     type B = Ty<'static>;
-    //~^ ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~^ ERROR struct takes 1 generic argument but 0 generic arguments
     //~| HELP add missing
 
     type C = Ty<usize>;
@@ -62,14 +62,14 @@
     type D = Ty<'static, usize>;
 
     type E = Ty<>;
-    //~^ ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~^ ERROR struct takes 1 generic argument but 0 generic arguments
     //~| ERROR missing lifetime specifier
     //~| HELP consider introducing
     //~| HELP add missing
 
     type F = Ty<'static, usize, 'static, usize>;
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments
-    //~| ERROR this struct takes 1 generic argument but 2 generic arguments
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments
+    //~| ERROR struct takes 1 generic argument but 2 generic arguments
     //~| HELP remove this lifetime argument
     //~| HELP remove this generic argument
 }
@@ -82,7 +82,7 @@
     //~| HELP add missing
 
     type B = Ty<usize>;
-    //~^ ERROR this struct takes at least 2
+    //~^ ERROR struct takes at least 2
     //~| HELP add missing
 
     type C = Ty<usize, String>;
@@ -90,11 +90,11 @@
     type D = Ty<usize, String, char>;
 
     type E = Ty<usize, String, char, f64>;
-    //~^ ERROR this struct takes at most 3
+    //~^ ERROR struct takes at most 3
     //~| HELP remove
 
     type F = Ty<>;
-    //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments
+    //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments
     //~| HELP add missing
 }
 
@@ -114,7 +114,7 @@
     }
 
     type A = Box<dyn NonGeneric<usize>>;
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| HELP remove
 
     type B = Box<dyn GenericLifetime>;
@@ -123,7 +123,7 @@
     //~| HELP consider making the bound lifetime-generic
 
     type C = Box<dyn GenericLifetime<'static, 'static>>;
-    //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
     //~| HELP remove
 
     type D = Box<dyn GenericType>;
@@ -131,7 +131,7 @@
     //~| HELP add missing
 
     type E = Box<dyn GenericType<String, usize>>;
-    //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+    //~^ ERROR trait takes 1 generic argument but 2 generic arguments
     //~| HELP remove
 
     type F = Box<dyn GenericLifetime<>>;
@@ -140,7 +140,7 @@
     //~| HELP consider making the bound lifetime-generic
 
     type G = Box<dyn GenericType<>>;
-    //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+    //~^ ERROR trait takes 1 generic argument but 0 generic arguments
     //~| HELP add missing
 }
 
@@ -151,7 +151,7 @@
         }
 
         type A = Box<dyn NonGenericAT<usize, AssocTy=()>>;
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         //~| HELP remove
     }
 
@@ -166,14 +166,14 @@
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
 
         type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~| ERROR trait takes 0 generic arguments but 1 generic argument
         //~| HELP remove
     }
 
@@ -183,17 +183,17 @@
         }
 
         type A = Box<dyn GenericTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
-        //~| ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+        //~| ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP remove
     }
 
@@ -203,20 +203,20 @@
         }
 
         type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
         //~| ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied
+        //~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
         //~| HELP add missing
 
         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type D = Box<dyn GenericLifetimeTypeAT<(), AssocTy=()>>;
@@ -228,21 +228,21 @@
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~| ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
 
         type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~^ ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
 
         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+        //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied
         //~| HELP remove
-        //~| ERROR this trait takes 1 generic argument but 2 generic arguments
+        //~| ERROR trait takes 1 generic argument but 2 generic arguments
         //~| HELP remove
     }
 
@@ -252,15 +252,15 @@
         }
 
         type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 0 generic arguments
+        //~^ ERROR trait takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 2 generic arguments but 1 generic argument
         //~| HELP add missing
 
         type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 generic arguments but 3 generic arguments
+        //~^ ERROR trait takes 2 generic arguments but 3 generic arguments
         //~| HELP remove
     }
 
@@ -275,7 +275,7 @@
         //~| HELP consider making the bound lifetime-generic
 
         type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
     }
 
@@ -288,17 +288,17 @@
         //~^ ERROR missing lifetime specifier
         //~| HELP consider introducing
         //~| HELP consider making the bound lifetime-generic
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
-        //~| ERROR this trait takes 1 generic argument but 0 generic arguments
+        //~| ERROR trait takes 1 generic argument but 0 generic arguments
         //~| HELP add missing
 
         type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>;
-        //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+        //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
         //~| HELP add missing lifetime argument
     }
 }
@@ -312,21 +312,21 @@
         //~| HELP add missing
 
         type B = HashMap<String>;
-        //~^ ERROR this struct takes at least
+        //~^ ERROR struct takes at least
         //~| HELP add missing
 
         type C = HashMap<'static>;
-        //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+        //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument
         //~| HELP remove these generics
-        //~| ERROR this struct takes at least 2
+        //~| ERROR struct takes at least 2
         //~| HELP add missing
 
         type D = HashMap<usize, String, char, f64>;
-        //~^ ERROR this struct takes at most 3
+        //~^ ERROR struct takes at most 3
         //~| HELP remove this
 
         type E = HashMap<>;
-        //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments
+        //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments
         //~| HELP add missing
     }
 
@@ -336,21 +336,21 @@
         //~| HELP add missing
 
         type B = Result<String>;
-        //~^ ERROR this enum takes 2 generic arguments but 1 generic argument
+        //~^ ERROR enum takes 2 generic arguments but 1 generic argument
         //~| HELP add missing
 
         type C = Result<'static>;
-        //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument
+        //~^ ERROR enum takes 0 lifetime arguments but 1 lifetime argument
         //~| HELP remove these generics
-        //~| ERROR this enum takes 2 generic arguments but 0 generic arguments
+        //~| ERROR enum takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
 
         type D = Result<usize, String, char>;
-        //~^ ERROR this enum takes 2 generic arguments but 3 generic arguments
+        //~^ ERROR enum takes 2 generic arguments but 3 generic arguments
         //~| HELP remove
 
         type E = Result<>;
-        //~^ ERROR this enum takes 2 generic arguments but 0 generic arguments
+        //~^ ERROR enum takes 2 generic arguments but 0 generic arguments
         //~| HELP add missing
     }
 }
diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr
index 75e33f6..9006fb1 100644
--- a/tests/ui/generics/wrong-number-of-args.stderr
+++ b/tests/ui/generics/wrong-number-of-args.stderr
@@ -167,7 +167,7 @@
 LL |         type A<'a> = Box<dyn GenericLifetimeLifetimeTypeAT<'a, 'a, AssocTy=()>>;
    |               ++++                                         +++++++
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:6:14
    |
 LL |     type B = Ty<'static>;
@@ -181,7 +181,7 @@
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:10:14
    |
 LL |     type C = Ty<'static, usize>;
@@ -195,7 +195,7 @@
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:10:14
    |
 LL |     type C = Ty<'static, usize>;
@@ -209,7 +209,7 @@
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:16:14
    |
 LL |     type D = Ty<'static, usize, { 0 }>;
@@ -223,7 +223,7 @@
 LL |     struct Ty;
    |            ^^
 
-error[E0107]: this struct takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:16:14
    |
 LL |     type D = Ty<'static, usize, { 0 }>;
@@ -253,7 +253,7 @@
 LL |     type A = Ty<A, B>;
    |                ++++++
 
-error[E0107]: this struct takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:30:14
    |
 LL |     type B = Ty<usize>;
@@ -271,7 +271,7 @@
 LL |     type B = Ty<usize, B>;
    |                      +++
 
-error[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:36:14
    |
 LL |     type D = Ty<usize, String, char>;
@@ -285,7 +285,7 @@
 LL |     struct Ty<A, B>;
    |            ^^ -  -
 
-error[E0107]: this struct takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:40:14
    |
 LL |     type E = Ty<>;
@@ -317,7 +317,7 @@
 LL |     type A = Ty<T>;
    |                +++
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:54:14
    |
 LL |     type B = Ty<'static>;
@@ -333,7 +333,7 @@
 LL |     type B = Ty<'static, T>;
    |                        +++
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:64:14
    |
 LL |     type E = Ty<>;
@@ -349,7 +349,7 @@
 LL |     type E = Ty<T>;
    |                 +
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:70:14
    |
 LL |     type F = Ty<'static, usize, 'static, usize>;
@@ -363,7 +363,7 @@
 LL |     struct Ty<'a, T>;
    |            ^^ --
 
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:70:14
    |
 LL |     type F = Ty<'static, usize, 'static, usize>;
@@ -393,7 +393,7 @@
 LL |     type A = Ty<A, B>;
    |                ++++++
 
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:84:14
    |
 LL |     type B = Ty<usize>;
@@ -411,7 +411,7 @@
 LL |     type B = Ty<usize, B>;
    |                      +++
 
-error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
+error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:92:14
    |
 LL |     type E = Ty<usize, String, char, f64>;
@@ -425,7 +425,7 @@
 LL |     struct Ty<A, B, C = &'static str>;
    |            ^^ -  -  ----------------
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:96:14
    |
 LL |     type F = Ty<>;
@@ -441,7 +441,7 @@
 LL |     type F = Ty<A, B>;
    |                 ++++
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:116:22
    |
 LL |     type A = Box<dyn NonGeneric<usize>>;
@@ -455,7 +455,7 @@
 LL |     trait NonGeneric {
    |           ^^^^^^^^^^
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:125:22
    |
 LL |     type C = Box<dyn GenericLifetime<'static, 'static>>;
@@ -485,7 +485,7 @@
 LL |     type D = Box<dyn GenericType<A>>;
    |                                 +++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:133:22
    |
 LL |     type E = Box<dyn GenericType<String, usize>>;
@@ -499,7 +499,7 @@
 LL |     trait GenericType<A> {
    |           ^^^^^^^^^^^ -
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:142:22
    |
 LL |     type G = Box<dyn GenericType<>>;
@@ -515,7 +515,7 @@
 LL |     type G = Box<dyn GenericType<A>>;
    |                                  +
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:153:26
    |
 LL |         type A = Box<dyn NonGenericAT<usize, AssocTy=()>>;
@@ -529,7 +529,7 @@
 LL |         trait NonGenericAT {
    |               ^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:168:26
    |
 LL |         type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>;
@@ -543,7 +543,7 @@
 LL |         trait GenericLifetimeAT<'a> {
    |               ^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:172:26
    |
 LL |         type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
@@ -557,7 +557,7 @@
 LL |         trait GenericLifetimeAT<'a> {
    |               ^^^^^^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:185:26
    |
 LL |         type A = Box<dyn GenericTypeAT<AssocTy=()>>;
@@ -573,7 +573,7 @@
 LL |         type A = Box<dyn GenericTypeAT<A, AssocTy=()>>;
    |                                        ++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:189:26
    |
 LL |         type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>;
@@ -587,7 +587,7 @@
 LL |         trait GenericTypeAT<A> {
    |               ^^^^^^^^^^^^^ -
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:193:26
    |
 LL |         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
@@ -601,7 +601,7 @@
 LL |         trait GenericTypeAT<A> {
    |               ^^^^^^^^^^^^^
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:193:26
    |
 LL |         type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>;
@@ -617,7 +617,7 @@
 LL |         type C = Box<dyn GenericTypeAT<'static, A, AssocTy=()>>;
    |                                               +++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:205:26
    |
 LL |         type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
@@ -633,7 +633,7 @@
 LL |         type A = Box<dyn GenericLifetimeTypeAT<A, AssocTy=()>>;
    |                                                ++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:212:26
    |
 LL |         type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>;
@@ -649,7 +649,7 @@
 LL |         type B = Box<dyn GenericLifetimeTypeAT<'static, A, AssocTy=()>>;
    |                                                       +++
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:216:26
    |
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
@@ -663,7 +663,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:216:26
    |
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>;
@@ -679,7 +679,7 @@
 LL |         type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, A, AssocTy=()>>;
    |                                                                +++
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:227:26
    |
 LL |         type E = Box<dyn GenericLifetimeTypeAT<(), (), AssocTy=()>>;
@@ -693,7 +693,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:234:26
    |
 LL |         type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
@@ -707,7 +707,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:238:26
    |
 LL |         type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>;
@@ -721,7 +721,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/wrong-number-of-args.rs:242:26
    |
 LL |         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
@@ -735,7 +735,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^ --
 
-error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:242:26
    |
 LL |         type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>;
@@ -749,7 +749,7 @@
 LL |         trait GenericLifetimeTypeAT<'a, A> {
    |               ^^^^^^^^^^^^^^^^^^^^^     -
 
-error[E0107]: this trait takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:254:26
    |
 LL |         type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>;
@@ -765,7 +765,7 @@
 LL |         type A = Box<dyn GenericTypeTypeAT<A, B, AssocTy=()>>;
    |                                            +++++
 
-error[E0107]: this trait takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:258:26
    |
 LL |         type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>;
@@ -783,7 +783,7 @@
 LL |         type B = Box<dyn GenericTypeTypeAT<(), B, AssocTy=()>>;
    |                                              +++
 
-error[E0107]: this trait takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:262:26
    |
 LL |         type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>;
@@ -797,7 +797,7 @@
 LL |         trait GenericTypeTypeAT<A, B> {
    |               ^^^^^^^^^^^^^^^^^ -  -
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:277:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>;
@@ -815,7 +815,7 @@
 LL |         type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'static, AssocTy=()>>;
    |                                                           +++++++++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:287:26
    |
 LL |         type A = Box<dyn GenericLifetimeLifetimeTypeAT<AssocTy=()>>;
@@ -831,7 +831,7 @@
 LL |         type A = Box<dyn GenericLifetimeLifetimeTypeAT<A, AssocTy=()>>;
    |                                                        ++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:294:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
@@ -849,7 +849,7 @@
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, AssocTy=()>>;
    |                                                               +++++++++
 
-error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:294:26
    |
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>;
@@ -865,7 +865,7 @@
 LL |         type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, A, AssocTy=()>>;
    |                                                               +++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:300:26
    |
 LL |         type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>;
@@ -894,7 +894,7 @@
 LL |         type A = HashMap<K, V>;
    |                         ++++++
 
-error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:314:18
    |
 LL |         type B = HashMap<String>;
@@ -907,7 +907,7 @@
 LL |         type B = HashMap<String, V>;
    |                                +++
 
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:318:18
    |
 LL |         type C = HashMap<'static>;
@@ -915,7 +915,7 @@
    |                  |
    |                  expected 0 lifetime arguments
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:318:18
    |
 LL |         type C = HashMap<'static>;
@@ -926,7 +926,7 @@
 LL |         type C = HashMap<'static, K, V>;
    |                                 ++++++
 
-error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
+error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:324:18
    |
 LL |         type D = HashMap<usize, String, char, f64>;
@@ -934,7 +934,7 @@
    |                  |
    |                  expected at most 3 generic arguments
 
-error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:328:18
    |
 LL |         type E = HashMap<>;
@@ -956,7 +956,7 @@
 LL |         type A = Result<T, E>;
    |                        ++++++
 
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/wrong-number-of-args.rs:338:18
    |
 LL |         type B = Result<String>;
@@ -969,7 +969,7 @@
 LL |         type B = Result<String, E>;
    |                               +++
 
-error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/wrong-number-of-args.rs:342:18
    |
 LL |         type C = Result<'static>;
@@ -977,7 +977,7 @@
    |                  |
    |                  expected 0 lifetime arguments
 
-error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:342:18
    |
 LL |         type C = Result<'static>;
@@ -988,7 +988,7 @@
 LL |         type C = Result<'static, T, E>;
    |                                ++++++
 
-error[E0107]: this enum takes 2 generic arguments but 3 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 3 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:348:18
    |
 LL |         type D = Result<usize, String, char>;
@@ -996,7 +996,7 @@
    |                  |
    |                  expected 2 generic arguments
 
-error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied
+error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied
   --> $DIR/wrong-number-of-args.rs:352:18
    |
 LL |         type E = Result<>;
diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
index c8b8278..9c10110 100644
--- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
+++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: function takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/explicit-generic-args-for-impl.rs:4:5
    |
 LL |     foo::<str, String>("".to_string());
diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
index 9d6db88..a26460c 100644
--- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
+++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/not-enough-args.rs:4:5
    |
 LL |     f::<[u8]>("a", b"a");
diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs
new file mode 100644
index 0000000..46ece72
--- /dev/null
+++ b/tests/ui/issues/issue-106755.rs
@@ -0,0 +1,19 @@
+// compile-flags:-Ztranslate-lang=en_US
+
+#![feature(negative_impls)]
+#![feature(marker_trait_attr)]
+
+#[marker]
+trait MyTrait {}
+
+struct TestType<T>(::std::marker::PhantomData<T>);
+
+unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+
+impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
+
+unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
+
+impl !Send for TestType<i32> {}
+
+fn main() {}
diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr
new file mode 100644
index 0000000..5439703
--- /dev/null
+++ b/tests/ui/issues/issue-106755.stderr
@@ -0,0 +1,22 @@
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
+  --> $DIR/issue-106755.rs:13:1
+   |
+LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+   | ------------------------------------------------------ positive implementation here
+LL |
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
+
+error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
+  --> $DIR/issue-106755.rs:15:1
+   |
+LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
+   | ------------------------------------------------------ first implementation here
+...
+LL | unsafe impl<T: 'static> Send for TestType<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0751.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/issues/issue-18423.rs b/tests/ui/issues/issue-18423.rs
index a81b32f..675fd04 100644
--- a/tests/ui/issues/issue-18423.rs
+++ b/tests/ui/issues/issue-18423.rs
@@ -2,7 +2,7 @@
 
 struct Foo<'a> {
     x: Box<'a, isize>
-    //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied
 }
 
 fn main() { }
diff --git a/tests/ui/issues/issue-18423.stderr b/tests/ui/issues/issue-18423.stderr
index bbf79366..5d154db 100644
--- a/tests/ui/issues/issue-18423.stderr
+++ b/tests/ui/issues/issue-18423.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/issue-18423.rs:4:8
    |
 LL |     x: Box<'a, isize>
diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/issues/issue-3214.rs
index 928a659..e3c07bb 100644
--- a/tests/ui/issues/issue-3214.rs
+++ b/tests/ui/issues/issue-3214.rs
@@ -4,7 +4,7 @@
     }
 
     impl<T> Drop for Foo<T> {
-        //~^ ERROR this struct takes 0 generic arguments but 1 generic argument
+        //~^ ERROR struct takes 0 generic arguments but 1 generic argument
         fn drop(&mut self) {}
     }
 }
diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/issues/issue-3214.stderr
index aa0b5ce..7a2d772 100644
--- a/tests/ui/issues/issue-3214.stderr
+++ b/tests/ui/issues/issue-3214.stderr
@@ -8,7 +8,7 @@
 LL |         x: T,
    |            ^ use of generic parameter from outer function
 
-error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-3214.rs:6:22
    |
 LL |     impl<T> Drop for Foo<T> {
diff --git a/tests/ui/issues/issue-53251.rs b/tests/ui/issues/issue-53251.rs
index 240826a..da3ba63 100644
--- a/tests/ui/issues/issue-53251.rs
+++ b/tests/ui/issues/issue-53251.rs
@@ -9,8 +9,8 @@
         $(
             fn $n() {
                 S::f::<i64>();
-                //~^ ERROR this associated function takes 0 generic
-                //~| ERROR this associated function takes 0 generic
+                //~^ ERROR associated function takes 0 generic
+                //~| ERROR associated function takes 0 generic
             }
         )*
     }
diff --git a/tests/ui/issues/issue-53251.stderr b/tests/ui/issues/issue-53251.stderr
index cee9a5d..d5f14e8 100644
--- a/tests/ui/issues/issue-53251.stderr
+++ b/tests/ui/issues/issue-53251.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-53251.rs:11:20
    |
 LL |                 S::f::<i64>();
@@ -16,7 +16,7 @@
    |        ^
    = note: this error originates in the macro `impl_add` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-53251.rs:11:20
    |
 LL |                 S::f::<i64>();
diff --git a/tests/ui/issues/issue-60622.rs b/tests/ui/issues/issue-60622.rs
index 7347957..7b9443e 100644
--- a/tests/ui/issues/issue-60622.rs
+++ b/tests/ui/issues/issue-60622.rs
@@ -9,7 +9,7 @@
 fn run_wild<T>(b: &Borked) {
     b.a::<'_, T>();
     //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
-    //~| ERROR this method takes 0 generic arguments but 1 generic argument
+    //~| ERROR method takes 0 generic arguments but 1 generic argument
     //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
diff --git a/tests/ui/issues/issue-60622.stderr b/tests/ui/issues/issue-60622.stderr
index 69b532b..43da277 100644
--- a/tests/ui/issues/issue-60622.stderr
+++ b/tests/ui/issues/issue-60622.stderr
@@ -16,7 +16,7 @@
    |         ^^^^^^^^
    = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]`
 
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-60622.rs:10:7
    |
 LL |     b.a::<'_, T>();
diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
index 0b331e2..792563f 100644
--- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
+++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
@@ -7,6 +7,6 @@
 type Alias<'a, T> = <T as Trait<'a>>::Assoc;
 
 fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
-//~^ error: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+//~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
 
 fn main() {}
diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
index 3704d9b..de58a01 100644
--- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
+++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/mismatched_arg_count.rs:9:29
    |
 LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
diff --git a/tests/ui/lint/issue-106991.rs b/tests/ui/lint/issue-106991.rs
new file mode 100644
index 0000000..e4d7f76
--- /dev/null
+++ b/tests/ui/lint/issue-106991.rs
@@ -0,0 +1,13 @@
+fn foo(items: &mut Vec<u8>) {
+    items.sort();
+}
+
+fn bar() -> impl Iterator<Item = i32> {
+    //~^ ERROR expected `foo` to be a fn item that returns `i32`, but it returns `()` [E0271]
+    let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
+    x.iter_mut().map(foo)
+}
+
+fn main() {
+    bar();
+}
diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr
new file mode 100644
index 0000000..7b43f0b
--- /dev/null
+++ b/tests/ui/lint/issue-106991.stderr
@@ -0,0 +1,11 @@
+error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns `()`
+  --> $DIR/issue-106991.rs:5:13
+   |
+LL | fn bar() -> impl Iterator<Item = i32> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `i32`
+   |
+   = note: required for `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` to implement `Iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/lint/lint_map_unit_fn.rs b/tests/ui/lint/lint_map_unit_fn.rs
new file mode 100644
index 0000000..dc1ecbf
--- /dev/null
+++ b/tests/ui/lint/lint_map_unit_fn.rs
@@ -0,0 +1,20 @@
+#![deny(map_unit_fn)]
+
+fn foo(items: &mut Vec<u8>) {
+    items.sort();
+}
+
+fn main() {
+    let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
+    x.iter_mut().map(foo);
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+    x.iter_mut().map(|items| {
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+        items.sort();
+    });
+    let f = |items: &mut Vec<u8>| {
+        items.sort();
+    };
+    x.iter_mut().map(f);
+    //~^ ERROR `Iterator::map` call that discard the iterator's values
+}
diff --git a/tests/ui/lint/lint_map_unit_fn.stderr b/tests/ui/lint/lint_map_unit_fn.stderr
new file mode 100644
index 0000000..fbf689c
--- /dev/null
+++ b/tests/ui/lint/lint_map_unit_fn.stderr
@@ -0,0 +1,66 @@
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:9:18
+   |
+LL | fn foo(items: &mut Vec<u8>) {
+   | --------------------------- this function returns `()`, which is likely not what you wanted
+...
+LL |     x.iter_mut().map(foo);
+   |                  ^^^^---^
+   |                  |   |
+   |                  |   called `Iterator::map` with callable that returns `()`
+   |                  after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+note: the lint level is defined here
+  --> $DIR/lint_map_unit_fn.rs:1:9
+   |
+LL | #![deny(map_unit_fn)]
+   |         ^^^^^^^^^^^
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(foo);
+   |                  ~~~~~~~~
+
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:11:18
+   |
+LL |         x.iter_mut().map(|items| {
+   |                      ^   -------
+   |                      |   |
+   |  ____________________|___this function returns `()`, which is likely not what you wanted
+   | |  __________________|
+   | | |
+LL | | |
+LL | | |         items.sort();
+LL | | |     });
+   | | |     -^ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   | | |_____||
+   | |_______|
+   |         called `Iterator::map` with callable that returns `()`
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(|items| {
+   |                  ~~~~~~~~
+
+error: `Iterator::map` call that discard the iterator's values
+  --> $DIR/lint_map_unit_fn.rs:18:18
+   |
+LL |     let f = |items: &mut Vec<u8>| {
+   |             --------------------- this function returns `()`, which is likely not what you wanted
+...
+LL |     x.iter_mut().map(f);
+   |                  ^^^^-^
+   |                  |   |
+   |                  |   called `Iterator::map` with callable that returns `()`
+   |                  after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
+   |
+   = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
+help: you might have meant to use `Iterator::for_each`
+   |
+LL |     x.iter_mut().for_each(f);
+   |                  ~~~~~~~~
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/methods/method-call-lifetime-args-fail.rs b/tests/ui/methods/method-call-lifetime-args-fail.rs
index 2e5c9a0..1f13de0 100644
--- a/tests/ui/methods/method-call-lifetime-args-fail.rs
+++ b/tests/ui/methods/method-call-lifetime-args-fail.rs
@@ -14,9 +14,9 @@
 fn method_call() {
     S.early(); // OK
     S.early::<'static>();
-    //~^ ERROR this method takes 2 lifetime arguments but 1 lifetime argument
+    //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument
     S.early::<'static, 'static, 'static>();
-    //~^ ERROR this method takes 2 lifetime arguments but 3 lifetime arguments were supplied
+    //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied
     let _: &u8 = S.life_and_type::<'static>();
     S.life_and_type::<u8>();
     S.life_and_type::<'static, u8>();
@@ -61,9 +61,9 @@
 
     S::early(S); // OK
     S::early::<'static>(S);
-    //~^ ERROR this method takes 2 lifetime arguments but 1 lifetime argument
+    //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument
     S::early::<'static, 'static, 'static>(S);
-    //~^ ERROR this method takes 2 lifetime arguments but 3 lifetime arguments were supplied
+    //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied
     let _: &u8 = S::life_and_type::<'static>(S);
     S::life_and_type::<u8>(S);
     S::life_and_type::<'static, u8>(S);
diff --git a/tests/ui/methods/method-call-lifetime-args-fail.stderr b/tests/ui/methods/method-call-lifetime-args-fail.stderr
index 45ff32b..3452625 100644
--- a/tests/ui/methods/method-call-lifetime-args-fail.stderr
+++ b/tests/ui/methods/method-call-lifetime-args-fail.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/method-call-lifetime-args-fail.rs:16:7
    |
 LL |     S.early::<'static>();
@@ -16,7 +16,7 @@
 LL |     S.early::<'static, 'static>();
    |                      +++++++++
 
-error[E0107]: this method takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/method-call-lifetime-args-fail.rs:18:7
    |
 LL |     S.early::<'static, 'static, 'static>();
@@ -198,7 +198,7 @@
 LL |     fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
    |                          ^^
 
-error[E0107]: this method takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/method-call-lifetime-args-fail.rs:63:8
    |
 LL |     S::early::<'static>(S);
@@ -216,7 +216,7 @@
 LL |     S::early::<'static, 'static>(S);
    |                       +++++++++
 
-error[E0107]: this method takes 2 lifetime arguments but 3 lifetime arguments were supplied
+error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied
   --> $DIR/method-call-lifetime-args-fail.rs:65:8
    |
 LL |     S::early::<'static, 'static, 'static>(S);
diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs
new file mode 100644
index 0000000..730e268
--- /dev/null
+++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![feature(const_trait_impl, rustc_attrs)]
+
+#[const_trait]
+trait Foo {
+    #[rustc_do_not_const_check]
+    fn into_iter(&self) { println!("FEAR ME!") }
+}
+
+
+impl const Foo for () {
+    fn into_iter(&self) {
+        // ^_^
+    }
+}
+
+const _: () = Foo::into_iter(&());
+
+fn main() {}
diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs
new file mode 100644
index 0000000..3c39c53
--- /dev/null
+++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(const_trait_impl, rustc_attrs)]
+
+#[const_trait]
+trait IntoIter {
+    fn into_iter(self);
+}
+
+#[const_trait]
+trait Hmm: Sized {
+    #[rustc_do_not_const_check]
+    fn chain<U>(self, other: U) where U: IntoIter,
+    {
+        other.into_iter()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/seq-args.rs b/tests/ui/seq-args.rs
index a5ebeec..627dfcc 100644
--- a/tests/ui/seq-args.rs
+++ b/tests/ui/seq-args.rs
@@ -2,12 +2,12 @@
     trait Seq { }
 
     impl<T> Seq<T> for Vec<T> {
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         /* ... */
     }
 
     impl Seq<bool> for u32 {
-        //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+        //~^ ERROR trait takes 0 generic arguments but 1 generic argument
         /* Treat the integer as a sequence of bits */
     }
 }
diff --git a/tests/ui/seq-args.stderr b/tests/ui/seq-args.stderr
index c404d95..a5b0f8e 100644
--- a/tests/ui/seq-args.stderr
+++ b/tests/ui/seq-args.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/seq-args.rs:4:13
    |
 LL |     impl<T> Seq<T> for Vec<T> {
@@ -12,7 +12,7 @@
 LL |     trait Seq { }
    |           ^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/seq-args.rs:9:10
    |
 LL |     impl Seq<bool> for u32 {
diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.rs b/tests/ui/stability-attribute/unresolved_stability_lint.rs
new file mode 100644
index 0000000..818d228
--- /dev/null
+++ b/tests/ui/stability-attribute/unresolved_stability_lint.rs
@@ -0,0 +1,8 @@
+#![feature(staged_api)]
+#![stable(feature = "uwu", since = "1.0.0")]
+
+#[unstable(feature = "foo", issue = "none")]
+impl Foo for () {}
+//~^ ERROR cannot find trait `Foo` in this scope
+
+fn main() {}
diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.stderr b/tests/ui/stability-attribute/unresolved_stability_lint.stderr
new file mode 100644
index 0000000..11d6abc
--- /dev/null
+++ b/tests/ui/stability-attribute/unresolved_stability_lint.stderr
@@ -0,0 +1,9 @@
+error[E0405]: cannot find trait `Foo` in this scope
+  --> $DIR/unresolved_stability_lint.rs:5:6
+   |
+LL | impl Foo for () {}
+   |      ^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0405`.
diff --git a/tests/ui/structs/struct-path-associated-type.rs b/tests/ui/structs/struct-path-associated-type.rs
index 2dd7174..74d9705 100644
--- a/tests/ui/structs/struct-path-associated-type.rs
+++ b/tests/ui/structs/struct-path-associated-type.rs
@@ -13,7 +13,7 @@
     //~^ ERROR expected struct, variant or union type, found associated type
     let z = T::A::<u8> {};
     //~^ ERROR expected struct, variant or union type, found associated type
-    //~| ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR associated type takes 0 generic arguments but 1 generic argument was supplied
     match S {
         T::A {} => {}
         //~^ ERROR expected struct, variant or union type, found associated type
@@ -22,7 +22,7 @@
 
 fn g<T: Tr<A = S>>() {
     let s = T::A {}; // OK
-    let z = T::A::<u8> {}; //~ ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied
+    let z = T::A::<u8> {}; //~ ERROR associated type takes 0 generic arguments but 1 generic argument was supplied
     match S {
         T::A {} => {} // OK
     }
diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr
index ca5f0b7..acfddaf 100644
--- a/tests/ui/structs/struct-path-associated-type.stderr
+++ b/tests/ui/structs/struct-path-associated-type.stderr
@@ -4,7 +4,7 @@
 LL |     let s = T::A {};
    |             ^^^^ not a struct
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/struct-path-associated-type.rs:14:16
    |
 LL |     let z = T::A::<u8> {};
@@ -30,7 +30,7 @@
 LL |         T::A {} => {}
    |         ^^^^ not a struct
 
-error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/struct-path-associated-type.rs:25:16
    |
 LL |     let z = T::A::<u8> {};
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.rs b/tests/ui/structs/structure-constructor-type-mismatch.rs
index a03ef59..21cd9d0 100644
--- a/tests/ui/structs/structure-constructor-type-mismatch.rs
+++ b/tests/ui/structs/structure-constructor-type-mismatch.rs
@@ -45,13 +45,13 @@
         y: 8,
     };
 
-    let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+    let pt3 = PointF::<i32> { //~ ERROR type alias takes 0 generic arguments but 1 generic argument
         x: 9,  //~ ERROR mismatched types
         y: 10, //~ ERROR mismatched types
     };
 
     match (Point { x: 1, y: 2 }) {
-        PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
+        PointF::<u32> { .. } => {} //~ ERROR type alias takes 0 generic arguments but 1 generic argument
         //~^ ERROR mismatched types
     }
 
diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr
index 3e3f9ea..63dda45 100644
--- a/tests/ui/structs/structure-constructor-type-mismatch.stderr
+++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr
@@ -52,7 +52,7 @@
    |            expected `f32`, found integer
    |            help: use a float literal: `7.0`
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:48:15
    |
 LL |     let pt3 = PointF::<i32> {
@@ -84,7 +84,7 @@
    |            expected `f32`, found integer
    |            help: use a float literal: `10.0`
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/structure-constructor-type-mismatch.rs:54:9
    |
 LL |         PointF::<u32> { .. } => {}
diff --git a/tests/ui/suggestions/issue-101421.rs b/tests/ui/suggestions/issue-101421.rs
index 53b1e88..1407ebd 100644
--- a/tests/ui/suggestions/issue-101421.rs
+++ b/tests/ui/suggestions/issue-101421.rs
@@ -8,5 +8,5 @@
 
 fn main() {
     ().f::<()>(());
-    //~^ ERROR this method takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
 }
diff --git a/tests/ui/suggestions/issue-101421.stderr b/tests/ui/suggestions/issue-101421.stderr
index 8362f02..2656ab3 100644
--- a/tests/ui/suggestions/issue-101421.stderr
+++ b/tests/ui/suggestions/issue-101421.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-101421.rs:10:8
    |
 LL |     ().f::<()>(());
diff --git a/tests/ui/suggestions/issue-104287.rs b/tests/ui/suggestions/issue-104287.rs
index 752282e..37b3339 100644
--- a/tests/ui/suggestions/issue-104287.rs
+++ b/tests/ui/suggestions/issue-104287.rs
@@ -8,6 +8,6 @@
 fn main() {
     let x = S;
     foo::<()>(x);
-    //~^ ERROR this method takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
     //~| ERROR cannot find function `foo` in this scope
 }
diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr
index d363601..ed59b2e 100644
--- a/tests/ui/suggestions/issue-104287.stderr
+++ b/tests/ui/suggestions/issue-104287.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-104287.rs:10:5
    |
 LL |     foo::<()>(x);
diff --git a/tests/ui/suggestions/issue-85347.rs b/tests/ui/suggestions/issue-85347.rs
index 02b5fb6..04d4c47 100644
--- a/tests/ui/suggestions/issue-85347.rs
+++ b/tests/ui/suggestions/issue-85347.rs
@@ -1,7 +1,7 @@
 use std::ops::Deref;
 trait Foo {
     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
-    //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
     //~| ERROR associated type bindings are not allowed here
     //~| HELP add missing
 }
diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr
index 17c1b7d..f330b3c 100644
--- a/tests/ui/suggestions/issue-85347.stderr
+++ b/tests/ui/suggestions/issue-85347.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/issue-85347.rs:3:42
    |
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
diff --git a/tests/ui/suggestions/issue-89064.stderr b/tests/ui/suggestions/issue-89064.stderr
index b238c18..be09dd8 100644
--- a/tests/ui/suggestions/issue-89064.stderr
+++ b/tests/ui/suggestions/issue-89064.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:17:16
    |
 LL |     let _ = A::foo::<S>();
@@ -20,7 +20,7 @@
 LL +     let _ = A::foo();
    |
 
-error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied
+error[E0107]: associated function takes 0 generic arguments but 2 generic arguments were supplied
   --> $DIR/issue-89064.rs:22:16
    |
 LL |     let _ = B::bar::<S, S>();
@@ -42,7 +42,7 @@
 LL +     let _ = B::bar();
    |
 
-error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:27:21
    |
 LL |     let _ = A::<S>::foo::<S>();
@@ -56,7 +56,7 @@
 LL |     fn foo() {}
    |        ^^^
 
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-89064.rs:31:16
    |
 LL |     let _ = 42.into::<Option<_>>();
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs
index 24f5f78..cb734e8 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.rs
+++ b/tests/ui/suggestions/missing-lifetime-specifier.rs
@@ -37,19 +37,19 @@
 
 thread_local! {
     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
-    //~^ ERROR this union takes 2 lifetime arguments but 1 lifetime argument
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR union takes 2 lifetime arguments but 1 lifetime argument
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied
 }
 thread_local! {
     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
-    //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-    //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+    //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied
     //~| ERROR missing lifetime
     //~| ERROR missing lifetime
 }
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr
index 997bbb5..21d2378 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr
@@ -133,7 +133,7 @@
    |
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -151,7 +151,7 @@
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -169,7 +169,7 @@
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -187,7 +187,7 @@
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -205,7 +205,7 @@
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:39:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -223,7 +223,7 @@
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                       +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -241,7 +241,7 @@
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -259,7 +259,7 @@
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -277,7 +277,7 @@
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -295,7 +295,7 @@
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/missing-lifetime-specifier.rs:47:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
diff --git a/tests/ui/suggestions/missing-type-param-used-in-param.stderr b/tests/ui/suggestions/missing-type-param-used-in-param.stderr
index 4f7058a..3116c5a 100644
--- a/tests/ui/suggestions/missing-type-param-used-in-param.stderr
+++ b/tests/ui/suggestions/missing-type-param-used-in-param.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/missing-type-param-used-in-param.rs:6:5
    |
 LL |     two_type_params::<String>(100);
diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
index 5e1f936..4066cd3 100644
--- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
+++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs
@@ -12,7 +12,7 @@
 
 fn main() {
     1.bar::<i32>(0);
-    //~^ ERROR this method takes 0 generic arguments but 1 generic argument was supplied
+    //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied
     //~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
     //~| HELP remove these generics
 }
diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
index 8ebff75..bfdb359 100644
--- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
+++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7
    |
 LL |     1.bar::<i32>(0);
diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
index fcff02e..4e3180e 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr
@@ -18,7 +18,7 @@
    = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
    = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
 
-error[E0107]: this struct takes at least 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied
   --> $DIR/type-ascription-instead-of-path-in-type.rs:6:12
    |
 LL |     let _: Vec<A:B> = A::B;
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
index 8b6e8cf..ed262fd 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs
@@ -6,7 +6,7 @@
 pub struct Foo {
     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
     //~^ ERROR must be specified
-    //~| ERROR this trait takes 2 generic arguments but 4 generic arguments were supplied
+    //~| ERROR trait takes 2 generic arguments but 4 generic arguments were supplied
 }
 
 
diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index 75b9192..175a5fb 100644
--- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 2 generic arguments but 4 generic arguments were supplied
+error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied
   --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
    |
 LL |     i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
diff --git a/tests/ui/tool-attributes/auxiliary/p1.rs b/tests/ui/tool-attributes/auxiliary/p1.rs
new file mode 100644
index 0000000..47195c7
--- /dev/null
+++ b/tests/ui/tool-attributes/auxiliary/p1.rs
@@ -0,0 +1,3 @@
+#![feature(rustc_attrs)]
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {}
diff --git a/tests/ui/tool-attributes/auxiliary/p2.rs b/tests/ui/tool-attributes/auxiliary/p2.rs
new file mode 100644
index 0000000..47195c7
--- /dev/null
+++ b/tests/ui/tool-attributes/auxiliary/p2.rs
@@ -0,0 +1,3 @@
+#![feature(rustc_attrs)]
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {}
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs
new file mode 100644
index 0000000..39c2ca1
--- /dev/null
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs
@@ -0,0 +1,13 @@
+// aux-build: p1.rs
+// aux-build: p2.rs
+
+// error-pattern: duplicate diagnostic item in crate `p2`
+// error-pattern: note: the diagnostic item is first defined in crate `p1`
+
+#![feature(rustc_attrs)]
+extern crate p1;
+extern crate p2;
+
+#[rustc_diagnostic_item = "Foo"]
+pub struct Foo {} //~ ERROR duplicate diagnostic item found
+fn main() {}
diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
new file mode 100644
index 0000000..e315fdc
--- /dev/null
+++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr
@@ -0,0 +1,12 @@
+error: duplicate diagnostic item in crate `p2`: `Foo`.
+   |
+   = note: the diagnostic item is first defined in crate `p1`.
+
+error: duplicate diagnostic item found: `Foo`.
+  --> $DIR/duplicate-diagnostic.rs:12:1
+   |
+LL | pub struct Foo {}
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/traits/object/vs-lifetime.rs b/tests/ui/traits/object/vs-lifetime.rs
index 14ae67c..d3e6c0b 100644
--- a/tests/ui/traits/object/vs-lifetime.rs
+++ b/tests/ui/traits/object/vs-lifetime.rs
@@ -9,8 +9,8 @@
     let _: S<'static, dyn 'static +>;
     //~^ at least one trait is required for an object type
     let _: S<'static, 'static>;
-    //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
+    //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied
     let _: S<dyn 'static +, 'static>;
     //~^ ERROR type provided when a lifetime was expected
     //~| ERROR at least one trait is required for an object type
diff --git a/tests/ui/traits/object/vs-lifetime.stderr b/tests/ui/traits/object/vs-lifetime.stderr
index 2244652..a69cd14 100644
--- a/tests/ui/traits/object/vs-lifetime.stderr
+++ b/tests/ui/traits/object/vs-lifetime.stderr
@@ -4,7 +4,7 @@
 LL |     let _: S<'static, dyn 'static +>;
    |                       ^^^^^^^^^^^^^
 
-error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
+error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied
   --> $DIR/vs-lifetime.rs:11:12
    |
 LL |     let _: S<'static, 'static>;
@@ -18,7 +18,7 @@
 LL | struct S<'a, T>(&'a u8, T);
    |        ^ --
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/vs-lifetime.rs:11:12
    |
 LL |     let _: S<'static, 'static>;
diff --git a/tests/ui/traits/test-2.rs b/tests/ui/traits/test-2.rs
index 3fb0cec..ffb778a 100644
--- a/tests/ui/traits/test-2.rs
+++ b/tests/ui/traits/test-2.rs
@@ -7,9 +7,9 @@
 
 fn main() {
     10.dup::<i32>();
-    //~^ ERROR this method takes 0 generic arguments but 1
+    //~^ ERROR method takes 0 generic arguments but 1
     10.blah::<i32, i32>();
-    //~^ ERROR this method takes 1 generic argument but 2
+    //~^ ERROR method takes 1 generic argument but 2
     (Box::new(10) as Box<dyn bar>).dup();
     //~^ ERROR E0038
     //~| ERROR E0038
diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr
index 2219ba9..6c0e8b8 100644
--- a/tests/ui/traits/test-2.stderr
+++ b/tests/ui/traits/test-2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/test-2.rs:9:8
    |
 LL |     10.dup::<i32>();
@@ -12,7 +12,7 @@
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |                ^^^
 
-error[E0107]: this method takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: method takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/test-2.rs:11:8
    |
 LL |     10.blah::<i32, i32>();
diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs
index 964a7e4..e5a56cc 100644
--- a/tests/ui/transmutability/issue-101739-2.rs
+++ b/tests/ui/transmutability/issue-101739-2.rs
@@ -15,7 +15,7 @@
         const ASSUME_VISIBILITY: bool,
     >()
     where
-        Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+        Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 3 generic arguments but 6 generic arguments were supplied
             Src,
             Context,
             ASSUME_ALIGNMENT,
diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr
index 1b3d202..420a9f3 100644
--- a/tests/ui/transmutability/issue-101739-2.stderr
+++ b/tests/ui/transmutability/issue-101739-2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied
+error[E0107]: trait takes at most 3 generic arguments but 6 generic arguments were supplied
   --> $DIR/issue-101739-2.rs:18:14
    |
 LL |           Dst: BikeshedIntrinsicFrom<
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
index 0031a46..759a7fd 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs
@@ -62,10 +62,10 @@
     AliasFixed::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::TSVariant(());
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::TSVariant::<()>(());
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 
     // Struct variant
 
@@ -80,10 +80,10 @@
     AliasFixed::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::SVariant { v: () };
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::SVariant::<()> { v: () };
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 
     // Unit variant
 
@@ -98,8 +98,8 @@
     AliasFixed::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
     AliasFixed::<()>::UVariant;
-    //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
     AliasFixed::<()>::UVariant::<()>;
     //~^ ERROR type arguments are not allowed on this type [E0109]
-    //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
+    //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
 }
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index a922d7a..758ff31 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -304,7 +304,7 @@
    |                 |
    |                 not allowed on this type
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:64:5
    |
 LL |     AliasFixed::<()>::TSVariant(());
@@ -318,7 +318,7 @@
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:66:5
    |
 LL |     AliasFixed::<()>::TSVariant::<()>(());
@@ -395,7 +395,7 @@
 LL +     AliasFixed::<()>::SVariant { v: () };
    |
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:82:5
    |
 LL |     AliasFixed::<()>::SVariant { v: () };
@@ -409,7 +409,7 @@
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:84:5
    |
 LL |     AliasFixed::<()>::SVariant::<()> { v: () };
@@ -470,7 +470,7 @@
    |                 |
    |                 not allowed on this type
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:100:5
    |
 LL |     AliasFixed::<()>::UVariant;
@@ -484,7 +484,7 @@
 LL | type AliasFixed = Enum<()>;
    |      ^^^^^^^^^^
 
-error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/enum-variant-generic-args.rs:102:5
    |
 LL |     AliasFixed::<()>::UVariant::<()>;
diff --git a/tests/ui/typeck/issue-75883.rs b/tests/ui/typeck/issue-75883.rs
index 885acc4..c50ea0a 100644
--- a/tests/ui/typeck/issue-75883.rs
+++ b/tests/ui/typeck/issue-75883.rs
@@ -4,7 +4,7 @@
 
 impl UI {
     pub fn run() -> Result<_> {
-        //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
+        //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied
         //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types
         let mut ui = UI {};
         ui.interact();
@@ -13,7 +13,7 @@
     }
 
     pub fn interact(&mut self) -> Result<_> {
-        //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
+        //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied
         //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types
         unimplemented!();
     }
diff --git a/tests/ui/typeck/issue-75883.stderr b/tests/ui/typeck/issue-75883.stderr
index f5adcab..a1ed084 100644
--- a/tests/ui/typeck/issue-75883.stderr
+++ b/tests/ui/typeck/issue-75883.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-75883.rs:6:21
    |
 LL |     pub fn run() -> Result<_> {
@@ -11,7 +11,7 @@
 LL |     pub fn run() -> Result<_, E> {
    |                             +++
 
-error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
+error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied
   --> $DIR/issue-75883.rs:15:35
    |
 LL |     pub fn interact(&mut self) -> Result<_> {
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
new file mode 100644
index 0000000..5ff567c
--- /dev/null
+++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Ztrait-solver=next
+// known-bug: unknown
+
+fn main() {
+    (0u8 + 0u8) as char;
+}
diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
new file mode 100644
index 0000000..6b09ccd
--- /dev/null
+++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr
@@ -0,0 +1,9 @@
+error[E0271]: type mismatch resolving `char == <u8 as Add>::Output`
+  --> $DIR/cast-checks-handling-projections.rs:5:5
+   |
+LL |     (0u8 + 0u8) as char;
+   |     ^^^^^^^^^^^ types differ
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
index c463a8a..7ff9199 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs
@@ -1,17 +1,17 @@
 fn foo1<T:Copy<U>, U>(x: T) {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 trait Trait: Copy<dyn Send> {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 struct MyStruct1<T: Copy<T>>;
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 struct MyStruct2<'a, T: Copy<'a>>;
-//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
 
 fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
-//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-//~| ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
+//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+//~| ERROR trait takes 0 generic arguments but 1 generic argument was supplied
 
 fn main() { }
diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
index 331540d..a71fd95 100644
--- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
+++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:1:11
    |
 LL | fn foo1<T:Copy<U>, U>(x: T) {}
@@ -6,7 +6,7 @@
    |           |
    |           expected 0 generic arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
    |
 LL | trait Trait: Copy<dyn Send> {}
@@ -14,7 +14,7 @@
    |              |
    |              expected 0 generic arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21
    |
 LL | struct MyStruct1<T: Copy<T>>;
@@ -22,7 +22,7 @@
    |                     |
    |                     expected 0 generic arguments
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25
    |
 LL | struct MyStruct2<'a, T: Copy<'a>>;
@@ -30,7 +30,7 @@
    |                         |
    |                         expected 0 lifetime arguments
 
-error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
+error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
@@ -38,7 +38,7 @@
    |               |
    |               expected 0 lifetime arguments
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
    |
 LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index b96c527..a450dbb 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -227,4 +227,6 @@
 }
 
 const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
+//~^ ERROR the trait bound
+//~| ERROR the trait bound
+//~| ERROR the placeholder
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index bc02547..bc6c9fd 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -437,17 +437,37 @@
    |                               not allowed in type signatures
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
+error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied
+  --> $DIR/typeck_type_placeholder_item.rs:229:22
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |                      ^^^^^^ `std::ops::Range<{integer}>` is not an iterator
+   |
+   = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>`
+note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const`
+  --> $DIR/typeck_type_placeholder_item.rs:229:14
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |              ^^^^^^^
+
+error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied
+  --> $DIR/typeck_type_placeholder_item.rs:229:45
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |                                             ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator
+   |
+   = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`
+note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const`
+  --> $DIR/typeck_type_placeholder_item.rs:229:14
+   |
+LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
   --> $DIR/typeck_type_placeholder_item.rs:229:10
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |          ^ not allowed in type signatures
-   |
-note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named
-  --> $DIR/typeck_type_placeholder_item.rs:229:14
-   |
-LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
   --> $DIR/typeck_type_placeholder_item.rs:140:31
@@ -657,7 +677,7 @@
    |              not allowed in type signatures
    |              help: replace with the correct type: `i32`
 
-error: aborting due to 71 previous errors
+error: aborting due to 73 previous errors
 
-Some errors have detailed explanations: E0121, E0282, E0403.
+Some errors have detailed explanations: E0121, E0277, E0282, E0403.
 For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
index 43e46c5..90b12ff 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs
@@ -7,5 +7,5 @@
 
 pub fn main() {
     let c: Foo<_, _> = Foo { r: &5 };
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
index a89c6b8..c4e4aed 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/typeck_type_placeholder_lifetime_1.rs:9:12
    |
 LL |     let c: Foo<_, _> = Foo { r: &5 };
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
index 178b8b1..e361312 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs
@@ -7,5 +7,5 @@
 
 pub fn main() {
     let c: Foo<_, usize> = Foo { r: &5 };
-    //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
+    //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied
 }
diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
index f30766b..3022317 100644
--- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
   --> $DIR/typeck_type_placeholder_lifetime_2.rs:9:12
    |
 LL |     let c: Foo<_, usize> = Foo { r: &5 };
diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.rs b/tests/ui/ufcs/ufcs-qpath-missing-params.rs
index a110bec..6ab6580c 100644
--- a/tests/ui/ufcs/ufcs-qpath-missing-params.rs
+++ b/tests/ui/ufcs/ufcs-qpath-missing-params.rs
@@ -15,6 +15,6 @@
       //~^ ERROR missing generics for
 
     <String as IntoCow>::into_cow::<str>("foo".to_string());
-    //~^ ERROR this method takes 0 generic arguments but 1
+    //~^ ERROR method takes 0 generic arguments but 1
     //~| ERROR missing generics for
 }
diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
index ace1c36..2338871 100644
--- a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr
@@ -30,7 +30,7 @@
 LL |     <String as IntoCow<B>>::into_cow::<str>("foo".to_string());
    |                       +++
 
-error[E0107]: this method takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/ufcs-qpath-missing-params.rs:17:26
    |
 LL |     <String as IntoCow>::into_cow::<str>("foo".to_string());
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
index 65f4007..c575f50 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
@@ -28,7 +28,7 @@
 }
 
 fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
-    //~^ ERROR this trait takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~^ ERROR trait takes 1 lifetime argument but 0 lifetime arguments were supplied
     // Here, the omitted lifetimes are expanded to distinct things.
     same_type(x, y)
 }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
index 016fc4d..8814617 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 1 lifetime argument but 0 lifetime arguments were supplied
+error[E0107]: trait takes 1 lifetime argument but 0 lifetime arguments were supplied
   --> $DIR/unboxed-closure-sugar-region.rs:30:51
    |
 LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
index 462f6fb..14d5646 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs
@@ -7,7 +7,7 @@
 fn bar() {
     let x: Box<Bar()> = panic!();
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments
 }
 
 fn main() { }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
index 29ea573..27b22c2 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
@@ -4,7 +4,7 @@
 LL |     let x: Box<Bar()> = panic!();
    |                ^^^^^ only `Fn` traits may use parentheses
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
    |
 LL |     let x: Box<Bar()> = panic!();
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
index bd61cbd..657b292 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs
@@ -6,7 +6,7 @@
 
 fn foo(b: Box<Bar()>) {
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| ERROR this struct takes 1 generic argument but 0 generic arguments
+    //~| ERROR struct takes 1 generic argument but 0 generic arguments
 }
 
 fn main() { }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
index 427ba34..94e42a6 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
@@ -4,7 +4,7 @@
 LL | fn foo(b: Box<Bar()>) {
    |               ^^^^^ only `Fn` traits may use parentheses
 
-error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
+error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied
   --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
    |
 LL | fn foo(b: Box<Bar()>) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
index f26ad8e..dd47ae7 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs
@@ -3,7 +3,7 @@
 trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
 
 fn foo(_: &dyn Three())
-//~^ ERROR this trait takes 3 generic arguments but 1 generic argument
+//~^ ERROR trait takes 3 generic arguments but 1 generic argument
 //~| ERROR associated type `Output` not found
 {}
 
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
index ebaacf0..5d7fe3f 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 3 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
    |
 LL | fn foo(_: &dyn Three())
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
index 4465b43..2c7e12f 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs
@@ -3,25 +3,25 @@
 trait Zero { fn dummy(&self); }
 
 fn foo1(_: dyn Zero()) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
 fn foo2(_: dyn Zero<usize>) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
 }
 
 fn foo3(_: dyn Zero <   usize   >) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
 }
 
 fn foo4(_: dyn Zero(usize)) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
 fn foo5(_: dyn Zero (   usize   )) {
-    //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+    //~^ ERROR trait takes 0 generic arguments but 1 generic argument
     //~| ERROR associated type `Output` not found for `Zero`
 }
 
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
index 9601e64..50b9055 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:16
    |
 LL | fn foo1(_: dyn Zero()) {
@@ -18,7 +18,7 @@
 LL | fn foo1(_: dyn Zero()) {
    |                ^^^^^^ associated type `Output` not found
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:10:16
    |
 LL | fn foo2(_: dyn Zero<usize>) {
@@ -32,7 +32,7 @@
 LL | trait Zero { fn dummy(&self); }
    |       ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:14:16
    |
 LL | fn foo3(_: dyn Zero <   usize   >) {
@@ -46,7 +46,7 @@
 LL | trait Zero { fn dummy(&self); }
    |       ^^^^
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:18:16
    |
 LL | fn foo4(_: dyn Zero(usize)) {
@@ -66,7 +66,7 @@
 LL | fn foo4(_: dyn Zero(usize)) {
    |                ^^^^^^^^^^^ associated type `Output` not found
 
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:23:16
    |
 LL | fn foo5(_: dyn Zero (   usize   )) {
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
index 4bcf905..ad60b0a 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs
@@ -3,7 +3,7 @@
 trait Trait {}
 
 fn f<F:Trait(isize) -> isize>(x: F) {}
-//~^ ERROR this trait takes 0 generic arguments but 1 generic argument
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument
 //~| ERROR associated type `Output` not found for `Trait`
 
 fn main() {}
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
index 3ff05fb..130b193 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
@@ -1,4 +1,4 @@
-error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:8
    |
 LL | fn f<F:Trait(isize) -> isize>(x: F) {}