about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_ast/src/ast.rs3
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs9
-rw-r--r--compiler/rustc_ast/src/util/parser.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs4
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs5
-rw-r--r--compiler/rustc_data_structures/Cargo.toml2
-rw-r--r--compiler/rustc_hir/src/hir.rs8
-rw-r--r--compiler/rustc_hir/src/intravisit.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs25
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/rvalue_scopes.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl5
-rw-r--r--compiler/rustc_lint/src/lints.rs4
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs1
-rw-r--r--compiler/rustc_lint/src/unused.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs10
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs11
-rw-r--r--compiler/rustc_passes/src/liveness.rs2
-rw-r--r--compiler/rustc_query_system/Cargo.toml2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs3
-rw-r--r--compiler/rustc_query_system/src/query/job.rs23
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_span/src/edit_distance.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/indexing_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/temporary_assignment.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs5
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs5
-rw-r--r--src/tools/rustfmt/src/expr.rs4
-rw-r--r--src/tools/rustfmt/src/matches.rs2
-rw-r--r--src/tools/rustfmt/src/utils.rs4
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/ui/array-slice-vec/slice-2.stderr16
-rw-r--r--tests/ui/borrowck/suggest-local-var-for-vector.stderr10
-rw-r--r--tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr10
-rw-r--r--tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr28
-rw-r--r--tests/ui/consts/issue-94675.stderr4
-rw-r--r--tests/ui/dst/issue-113447.fixed25
-rw-r--r--tests/ui/dst/issue-113447.rs25
-rw-r--r--tests/ui/dst/issue-113447.stderr25
-rw-r--r--tests/ui/error-codes/E0608.stderr4
-rw-r--r--tests/ui/indexing/index-bot.rs (renamed from tests/ui/index-bot.rs)0
-rw-r--r--tests/ui/indexing/index-bot.stderr (renamed from tests/ui/index-bot.stderr)4
-rw-r--r--tests/ui/indexing/index-help.rs (renamed from tests/ui/index-help.rs)0
-rw-r--r--tests/ui/indexing/index-help.stderr (renamed from tests/ui/index-help.stderr)0
-rw-r--r--tests/ui/indexing/index_message.rs (renamed from tests/ui/index_message.rs)0
-rw-r--r--tests/ui/indexing/index_message.stderr (renamed from tests/ui/index_message.stderr)4
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.rs (renamed from tests/ui/indexing-requires-a-uint.rs)0
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr (renamed from tests/ui/indexing-requires-a-uint.stderr)0
-rw-r--r--tests/ui/indexing/indexing-spans-caller-location.rs27
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--tests/ui/invalid/issue-114435-layout-type-err.rs44
-rw-r--r--tests/ui/invalid/issue-114435-layout-type-err.stderr8
-rw-r--r--tests/ui/issues/issue-27842.stderr12
-rw-r--r--tests/ui/issues/issue-40861.stderr4
-rw-r--r--tests/ui/lint/lint-unconditional-recursion.stderr2
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs4
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr12
-rw-r--r--tests/ui/moves/use_of_moved_value_clone_suggestions.stderr2
-rw-r--r--tests/ui/span/suggestion-non-ascii.stderr4
-rw-r--r--tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr4
-rw-r--r--tests/ui/typeck/issue-114423.rs15
-rw-r--r--tests/ui/typeck/issue-114423.stderr52
111 files changed, 466 insertions, 202 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4474f79599e..7cde7989bc0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3469,7 +3469,7 @@ dependencies = [
  "libc",
  "measureme",
  "memmap2",
- "parking_lot 0.11.2",
+ "parking_lot 0.12.1",
  "rustc-hash",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -4190,7 +4190,7 @@ dependencies = [
 name = "rustc_query_system"
 version = "0.0.0"
 dependencies = [
- "parking_lot 0.11.2",
+ "parking_lot 0.12.1",
  "rustc-rayon-core",
  "rustc_ast",
  "rustc_data_structures",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 2a268c2da85..f2e90fd8eed 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1462,7 +1462,8 @@ pub enum ExprKind {
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
     Field(P<Expr>, Ident),
     /// An indexing operation (e.g., `foo[2]`).
-    Index(P<Expr>, P<Expr>),
+    /// The span represents the span of the `[2]`, including brackets.
+    Index(P<Expr>, P<Expr>, Span),
     /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
     Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
     /// An underscore, used in destructuring assignment to ignore a value.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 84b56efd325..bae3979fbf9 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1400,7 +1400,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
             fn_decl,
             body,
             fn_decl_span,
-            fn_arg_span: _,
+            fn_arg_span,
         }) => {
             vis.visit_closure_binder(binder);
             visit_constness(constness, vis);
@@ -1408,6 +1408,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_fn_decl(fn_decl);
             vis.visit_expr(body);
             vis.visit_span(fn_decl_span);
+            vis.visit_span(fn_arg_span);
         }
         ExprKind::Block(blk, label) => {
             vis.visit_block(blk);
@@ -1420,9 +1421,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_expr(expr);
             vis.visit_span(await_kw_span);
         }
-        ExprKind::Assign(el, er, _) => {
+        ExprKind::Assign(el, er, span) => {
             vis.visit_expr(el);
             vis.visit_expr(er);
+            vis.visit_span(span);
         }
         ExprKind::AssignOp(_op, el, er) => {
             vis.visit_expr(el);
@@ -1432,9 +1434,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
             vis.visit_expr(el);
             vis.visit_ident(ident);
         }
-        ExprKind::Index(el, er) => {
+        ExprKind::Index(el, er, brackets_span) => {
             vis.visit_expr(el);
             vis.visit_expr(er);
+            vis.visit_span(brackets_span);
         }
         ExprKind::Range(e1, e2, _lim) => {
             visit_opt(e1, |e1| vis.visit_expr(e1));
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 096077e09bf..d3e43e20235 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -390,7 +390,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
         | ast::ExprKind::Cast(x, _)
         | ast::ExprKind::Type(x, _)
         | ast::ExprKind::Field(x, _)
-        | ast::ExprKind::Index(x, _) => {
+        | ast::ExprKind::Index(x, _, _) => {
             // &X { y: 1 }, X { y: 1 }.y
             contains_exterior_struct_lit(x)
         }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index aed24e11c4e..6d474de2d15 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -885,7 +885,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             visitor.visit_expr(subexpression);
             visitor.visit_ident(*ident);
         }
-        ExprKind::Index(main_expression, index_expression) => {
+        ExprKind::Index(main_expression, index_expression, _) => {
             visitor.visit_expr(main_expression);
             visitor.visit_expr(index_expression)
         }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 0954cf03da9..8c35266110e 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -240,8 +240,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::Field(el, ident) => {
                     hir::ExprKind::Field(self.lower_expr(el), self.lower_ident(*ident))
                 }
-                ExprKind::Index(el, er) => {
-                    hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er))
+                ExprKind::Index(el, er, brackets_span) => {
+                    hir::ExprKind::Index(self.lower_expr(el), self.lower_expr(er), *brackets_span)
                 }
                 ExprKind::Range(Some(e1), Some(e2), RangeLimits::Closed) => {
                     self.lower_expr_range_closed(e.span, e1, e2)
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 8767bbcb210..39741a03930 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -477,7 +477,7 @@ impl<'a> State<'a> {
                 self.word(".");
                 self.print_ident(*ident);
             }
-            ast::ExprKind::Index(expr, index) => {
+            ast::ExprKind::Index(expr, index, _) => {
                 self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
                 self.word("[");
                 self.print_expr(index);
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 28c0a444fc8..fe4a45b3898 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -751,9 +751,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
                 .must_apply_modulo_regions()
         {
+            let msg = if let ty::Adt(def, _) = ty.kind()
+                && [
+                    tcx.get_diagnostic_item(sym::Arc),
+                    tcx.get_diagnostic_item(sym::Rc),
+                ].contains(&Some(def.did()))
+            {
+                "clone the value to increment its reference count"
+            } else {
+                "consider cloning the value if the performance cost is acceptable"
+            };
             err.span_suggestion_verbose(
                 span.shrink_to_hi(),
-                "consider cloning the value if the performance cost is acceptable",
+                msg,
                 suggestion,
                 Applicability::MachineApplicable,
             );
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index c92f32071f4..c66a2447356 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -79,7 +79,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
                         | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
                         | hir::ExprKind::Field(inner, _)
                         | hir::ExprKind::MethodCall(_, inner, _, _)
-                        | hir::ExprKind::Index(inner, _) = &expr.kind
+                        | hir::ExprKind::Index(inner, _, _) = &expr.kind
                     {
                         expr = inner;
                     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 3c32121a51a..d62541daf07 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -567,7 +567,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         }
                     };
                     if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
-                        && let hir::ExprKind::Index(val, index) = place.kind
+                        && let hir::ExprKind::Index(val, index, _) = place.kind
                         && (expr.span == self.assign_span || place.span == self.assign_span)
                     {
                         // val[index] = rv;
@@ -620,7 +620,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         );
                         self.suggested = true;
                     } else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
-                        && let hir::ExprKind::Index(val, index) = receiver.kind
+                        && let hir::ExprKind::Index(val, index, _) = receiver.kind
                         && expr.span == self.assign_span
                     {
                         // val[index].path(args..);
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index cbf115127cf..bda473120ed 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -237,7 +237,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
             ExprKind::If(local_expr, _, _) => {
                 self.manage_cond_expr(local_expr);
             }
-            ExprKind::Index(prefix, suffix) => {
+            ExprKind::Index(prefix, suffix, _) => {
                 self.manage_cond_expr(prefix);
                 self.manage_cond_expr(suffix);
             }
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 67ea20112fe..3081dcfa2b7 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -477,7 +477,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
 
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
-        if let layout::LayoutError::SizeOverflow(_) = err {
+        if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.0.sess.span_fatal(span, err.to_string())
         } else {
             span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index 08507e19652..88dcafa7370 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -476,7 +476,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
 
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
-        if let LayoutError::SizeOverflow(_) = err {
+        if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.sess().emit_fatal(respan(span, err.into_diagnostic()))
         } else {
             span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index cb093996d1d..3577fb2d951 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -985,7 +985,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
 
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
-        if let LayoutError::SizeOverflow(_) = err {
+        if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
             self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() })
         } else {
             span_bug!(span, "failed to get layout for `{ty}`: {err:?}")
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 5f4f5434b18..2dc856528f5 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -157,7 +157,6 @@ impl<Prov: Provenance> MemPlace<Prov> {
     }
 
     /// Turn a mplace into a (thin or wide) pointer, as a reference, pointing to the same space.
-    /// This is the inverse of `ref_to_mplace`.
     #[inline(always)]
     pub fn to_ref(self, cx: &impl HasDataLayout) -> Immediate<Prov> {
         match self.meta {
@@ -415,7 +414,7 @@ where
     }
 
     /// Take a value, which represents a (thin or wide) reference, and make it a place.
-    /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
+    /// Alignment is just based on the type. This is the inverse of `mplace_to_ref()`.
     ///
     /// Only call this if you are sure the place is "valid" (aligned and inbounds), or do not
     /// want to ever use the place for memory access!
@@ -438,6 +437,18 @@ where
         Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.to_pointer(self)?, layout, meta))
     }
 
+    /// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space.
+    /// `align` information is lost!
+    /// This is the inverse of `ref_to_mplace`.
+    pub fn mplace_to_ref(
+        &self,
+        mplace: &MPlaceTy<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
+        let imm = mplace.to_ref(self);
+        let layout = self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, mplace.layout.ty))?;
+        Ok(ImmTy::from_immediate(imm, layout))
+    }
+
     /// Take an operand, representing a pointer, and dereference it to a place.
     /// Corresponds to the `*` operator in Rust.
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index bf33c5cca10..1bd21473182 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -852,10 +852,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let instance = ty::Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
         let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
 
-        let arg = ImmTy::from_immediate(
-            place.to_ref(self),
-            self.layout_of(Ty::new_mut_ptr(self.tcx.tcx, place.layout.ty))?,
-        );
+        let arg = self.mplace_to_ref(&place)?;
         let ret = MPlaceTy::fake_alloc_zst(self.layout_of(self.tcx.types.unit)?);
 
         self.eval_fn_call(
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index a5c3cb3f857..f77bd53e76c 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -35,7 +35,7 @@ elsa = "=1.7.1"
 itertools = "0.10.1"
 
 [dependencies.parking_lot]
-version = "0.11"
+version = "0.12"
 
 [target.'cfg(windows)'.dependencies.windows]
 version = "0.48.0"
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 6b76e16825f..bc05565fed4 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1754,7 +1754,7 @@ impl Expr<'_> {
 
             ExprKind::Unary(UnOp::Deref, _) => true,
 
-            ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _) => {
+            ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
                 allow_projections_from(base) || base.is_place_expr(allow_projections_from)
             }
 
@@ -1831,7 +1831,7 @@ impl Expr<'_> {
             ExprKind::Type(base, _)
             | ExprKind::Unary(_, base)
             | ExprKind::Field(base, _)
-            | ExprKind::Index(base, _)
+            | ExprKind::Index(base, _, _)
             | ExprKind::AddrOf(.., base)
             | ExprKind::Cast(base, _) => {
                 // This isn't exactly true for `Index` and all `Unary`, but we are using this
@@ -2015,7 +2015,9 @@ pub enum ExprKind<'hir> {
     /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
     Field(&'hir Expr<'hir>, Ident),
     /// An indexing operation (`foo[2]`).
-    Index(&'hir Expr<'hir>, &'hir Expr<'hir>),
+    /// Similar to [`ExprKind::MethodCall`], the final `Span` represents the span of the brackets
+    /// and index.
+    Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
 
     /// Path to a definition, possibly containing lifetime or type parameters.
     Path(QPath<'hir>),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index a8a94e6a476..9d1d899eef0 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -780,7 +780,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
             visitor.visit_expr(subexpression);
             visitor.visit_ident(ident);
         }
-        ExprKind::Index(ref main_expression, ref index_expression) => {
+        ExprKind::Index(ref main_expression, ref index_expression, _) => {
             visitor.visit_expr(main_expression);
             visitor.visit_expr(index_expression)
         }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 2d8b956771b..fda46798708 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1526,7 +1526,7 @@ impl<'a> State<'a> {
                 self.word(".");
                 self.print_ident(ident);
             }
-            hir::ExprKind::Index(expr, index) => {
+            hir::ExprKind::Index(expr, index, _) => {
                 self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
                 self.word("[");
                 self.print_expr(index);
@@ -2419,7 +2419,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
         | hir::ExprKind::Cast(x, _)
         | hir::ExprKind::Type(x, _)
         | hir::ExprKind::Field(x, _)
-        | hir::ExprKind::Index(x, _) => {
+        | hir::ExprKind::Index(x, _, _) => {
             // `&X { y: 1 }, X { y: 1 }.y`
             contains_exterior_struct_lit(x)
         }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 80d7cc57edb..2af8648455b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -345,7 +345,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
             }
             ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected),
-            ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr),
+            ExprKind::Index(base, idx, brackets_span) => {
+                self.check_expr_index(base, idx, expr, brackets_span)
+            }
             ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src),
             hir::ExprKind::Err(guar) => Ty::new_error(tcx, guar),
         }
@@ -2840,6 +2842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base: &'tcx hir::Expr<'tcx>,
         idx: &'tcx hir::Expr<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
+        brackets_span: Span,
     ) -> Ty<'tcx> {
         let base_t = self.check_expr(&base);
         let idx_t = self.check_expr(&idx);
@@ -2873,7 +2876,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     let mut err = type_error_struct!(
                         self.tcx.sess,
-                        expr.span,
+                        brackets_span,
                         base_t,
                         E0608,
                         "cannot index into a value of type `{base_t}`",
@@ -2887,16 +2890,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             && let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
                             && i < types.len().try_into().expect("expected tuple index to be < usize length")
                         {
-                            let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
-                            if let Ok(snip) = snip {
-                                err.span_suggestion(
-                                    expr.span,
-                                    "to access tuple elements, use",
-                                    format!("{snip}.{i}"),
-                                    Applicability::MachineApplicable,
-                                );
-                                needs_note = false;
-                            }
+
+                            err.span_suggestion(
+                                brackets_span,
+                                "to access tuple elements, use",
+                                format!(".{i}"),
+                                Applicability::MachineApplicable,
+                            );
+                            needs_note = false;
                         } else if let ExprKind::Path(..) = idx.peel_borrows().kind {
                             err.span_label(idx.span, "cannot access tuple elements at a variable index");
                         }
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index a59061cbf67..840910732d8 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -211,7 +211,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 self.select_from_expr(base);
             }
 
-            hir::ExprKind::Index(lhs, rhs) => {
+            hir::ExprKind::Index(lhs, rhs, _) => {
                 // lhs[rhs]
                 self.select_from_expr(lhs);
                 self.consume_expr(rhs);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index d4edd08d302..89bbb4c2203 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1620,8 +1620,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     .iter()
                                     .enumerate()
                                     .filter(|x| x.1.hir_id == *hir_id)
-                                    .map(|(i, _)| init_tup.get(i).unwrap())
-                                    .next()
+                                    .find_map(|(i, _)| init_tup.get(i))
                                 {
                                     self.note_type_is_not_clone_inner_expr(init)
                                 } else {
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index e91103f2130..4ea53c7eaae 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -332,7 +332,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 ))
             }
 
-            hir::ExprKind::Index(ref base, _) => {
+            hir::ExprKind::Index(ref base, _, _) => {
                 if self.typeck_results.is_method_call(expr) {
                     // If this is an index implemented by a method call, then it
                     // will include an implicit deref of the result.
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index 1eb84eb1637..406434e09e6 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut exprs = vec![expr];
 
         while let hir::ExprKind::Field(ref expr, _)
-        | hir::ExprKind::Index(ref expr, _)
+        | hir::ExprKind::Index(ref expr, _, _)
         | hir::ExprKind::Unary(hir::UnOp::Deref, ref expr) = exprs.last().unwrap().kind
         {
             exprs.push(expr);
diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
index 091e88abe97..04d84102336 100644
--- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
+++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
@@ -40,7 +40,7 @@ fn record_rvalue_scope_rec(
             hir::ExprKind::AddrOf(_, _, subexpr)
             | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
             | hir::ExprKind::Field(subexpr, _)
-            | hir::ExprKind::Index(subexpr, _) => {
+            | hir::ExprKind::Index(subexpr, _, _) => {
                 expr = subexpr;
             }
             _ => {
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 6f47623ec43..603681bbc99 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -210,7 +210,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     // to use builtin indexing because the index type is known to be
     // usize-ish
     fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
-        if let hir::ExprKind::Index(ref base, ref index) = e.kind {
+        if let hir::ExprKind::Index(ref base, ref index, _) = e.kind {
             // All valid indexing looks like this; might encounter non-valid indexes at this point.
             let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
             if base_ty.is_none() {
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 92a09aa6a53..c4a7f717840 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -167,8 +167,9 @@ lint_check_name_warning = {$msg}
 
 lint_command_line_source = `forbid` lint level was set on command line
 
-lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
-    .label = this is where the previous identifier occurred
+lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike
+    .current_use = this identifier can be confused with `{$existing_sym}`
+    .other_use = other identifier used here
 
 lint_cstring_ptr = getting the inner pointer of a temporary `CString`
     .as_ptr_label = this pointer will be invalid
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 07bcf96899c..43b3ee9e912 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1083,8 +1083,10 @@ pub struct IdentifierUncommonCodepoints;
 pub struct ConfusableIdentifierPair {
     pub existing_sym: Symbol,
     pub sym: Symbol,
-    #[label]
+    #[label(lint_other_use)]
     pub label: Span,
+    #[label(lint_current_use)]
+    pub main_label: Span,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index 4af879b4e91..62bb8c2c67d 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -222,6 +222,7 @@ impl EarlyLintPass for NonAsciiIdents {
                                     existing_sym: *existing_symbol,
                                     sym: symbol,
                                     label: *existing_span,
+                                    main_label: sp,
                                 },
                             );
                         }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index a3c5ca4cda1..3db6b302790 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -653,7 +653,7 @@ trait UnusedDelimLint {
                     ExprKind::Call(fn_, _params) => fn_,
                     ExprKind::Cast(expr, _ty) => expr,
                     ExprKind::Type(expr, _ty) => expr,
-                    ExprKind::Index(base, _subscript) => base,
+                    ExprKind::Index(base, _subscript, _) => base,
                     _ => break,
                 };
                 if !classify::expr_requires_semi_to_be_stmt(innermost) {
@@ -830,7 +830,7 @@ trait UnusedDelimLint {
                 (value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true)
             }
 
-            Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
+            Index(_, ref value, _) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
 
             Assign(_, ref value, _) | AssignOp(.., ref value) => {
                 (value, UnusedDelimsCtx::AssignedValue, false, None, None, false)
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index b907b69224c..994ac8a3286 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -469,11 +469,17 @@ impl<'tcx> Cx<'tcx> {
                 }
             }
 
-            hir::ExprKind::Index(ref lhs, ref index) => {
+            hir::ExprKind::Index(ref lhs, ref index, brackets_span) => {
                 if self.typeck_results().is_method_call(expr) {
                     let lhs = self.mirror_expr(lhs);
                     let index = self.mirror_expr(index);
-                    self.overloaded_place(expr, expr_ty, None, Box::new([lhs, index]), expr.span)
+                    self.overloaded_place(
+                        expr,
+                        expr_ty,
+                        None,
+                        Box::new([lhs, index]),
+                        brackets_span,
+                    )
                 } else {
                     ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
                 }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index c0459789805..e409c7c6781 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
             let msg = format!(
                 "cast cannot be followed by {}",
                 match with_postfix.kind {
-                    ExprKind::Index(_, _) => "indexing",
+                    ExprKind::Index(..) => "indexing",
                     ExprKind::Try(_) => "`?`",
                     ExprKind::Field(_, _) => "a field access",
                     ExprKind::MethodCall(_) => "a method call",
@@ -1304,7 +1304,10 @@ impl<'a> Parser<'a> {
         let index = self.parse_expr()?;
         self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
         self.expect(&token::CloseDelim(Delimiter::Bracket))?;
-        Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index)))
+        Ok(self.mk_expr(
+            lo.to(self.prev_token.span),
+            self.mk_index(base, index, open_delim_span.to(self.prev_token.span)),
+        ))
     }
 
     /// Assuming we have just parsed `.`, continue parsing into an expression.
@@ -3366,8 +3369,8 @@ impl<'a> Parser<'a> {
         ExprKind::Binary(binop, lhs, rhs)
     }
 
-    fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind {
-        ExprKind::Index(expr, idx)
+    fn mk_index(&self, expr: P<Expr>, idx: P<Expr>, brackets_span: Span) -> ExprKind {
+        ExprKind::Index(expr, idx, brackets_span)
     }
 
     fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind {
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 15757a0f1ad..0c0b8b6d094 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1061,7 +1061,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 self.propagate_through_expr(&l, ln)
             }
 
-            hir::ExprKind::Index(ref l, ref r) | hir::ExprKind::Binary(_, ref l, ref r) => {
+            hir::ExprKind::Index(ref l, ref r, _) | hir::ExprKind::Binary(_, ref l, ref r) => {
                 let r_succ = self.propagate_through_expr(&r, succ);
                 self.propagate_through_expr(&l, r_succ)
             }
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index e02cf38b671..584355df802 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2021"
 [lib]
 
 [dependencies]
-parking_lot = "0.11"
+parking_lot = "0.12"
 rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index b87757a3e1a..3803f7eca0a 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -1,4 +1,3 @@
-use parking_lot::Mutex;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef};
@@ -88,7 +87,7 @@ pub struct DepGraphData<K: DepKind> {
 
     colors: DepNodeColorMap,
 
-    processed_side_effects: Mutex<FxHashSet<DepNodeIndex>>,
+    processed_side_effects: Lock<FxHashSet<DepNodeIndex>>,
 
     /// When we load, there may be `.o` files, cached MIR, or other such
     /// things available to us. If we find that they are not dirty, we
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index d2140161f1d..bfc51da170d 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -21,12 +21,11 @@ use {
     parking_lot::{Condvar, Mutex},
     rayon_core,
     rustc_data_structures::fx::FxHashSet,
-    rustc_data_structures::sync::Lock,
-    rustc_data_structures::sync::Lrc,
     rustc_data_structures::{defer, jobserver},
     rustc_span::DUMMY_SP,
     std::iter,
     std::process,
+    std::sync::Arc,
 };
 
 /// Represents a span and a query key.
@@ -191,7 +190,7 @@ struct QueryWaiter<D: DepKind> {
     query: Option<QueryJobId>,
     condvar: Condvar,
     span: Span,
-    cycle: Lock<Option<CycleError<D>>>,
+    cycle: Mutex<Option<CycleError<D>>>,
 }
 
 #[cfg(parallel_compiler)]
@@ -205,20 +204,20 @@ impl<D: DepKind> QueryWaiter<D> {
 #[cfg(parallel_compiler)]
 struct QueryLatchInfo<D: DepKind> {
     complete: bool,
-    waiters: Vec<Lrc<QueryWaiter<D>>>,
+    waiters: Vec<Arc<QueryWaiter<D>>>,
 }
 
 #[cfg(parallel_compiler)]
 #[derive(Clone)]
 pub(super) struct QueryLatch<D: DepKind> {
-    info: Lrc<Mutex<QueryLatchInfo<D>>>,
+    info: Arc<Mutex<QueryLatchInfo<D>>>,
 }
 
 #[cfg(parallel_compiler)]
 impl<D: DepKind> QueryLatch<D> {
     fn new() -> Self {
         QueryLatch {
-            info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })),
+            info: Arc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })),
         }
     }
 
@@ -229,11 +228,11 @@ impl<D: DepKind> QueryLatch<D> {
         span: Span,
     ) -> Result<(), CycleError<D>> {
         let waiter =
-            Lrc::new(QueryWaiter { query, span, cycle: Lock::new(None), condvar: Condvar::new() });
+            Arc::new(QueryWaiter { query, span, cycle: Mutex::new(None), condvar: Condvar::new() });
         self.wait_on_inner(&waiter);
         // FIXME: Get rid of this lock. We have ownership of the QueryWaiter
-        // although another thread may still have a Lrc reference so we cannot
-        // use Lrc::get_mut
+        // although another thread may still have a Arc reference so we cannot
+        // use Arc::get_mut
         let mut cycle = waiter.cycle.lock();
         match cycle.take() {
             None => Ok(()),
@@ -242,7 +241,7 @@ impl<D: DepKind> QueryLatch<D> {
     }
 
     /// Awaits the caller on this latch by blocking the current thread.
-    fn wait_on_inner(&self, waiter: &Lrc<QueryWaiter<D>>) {
+    fn wait_on_inner(&self, waiter: &Arc<QueryWaiter<D>>) {
         let mut info = self.info.lock();
         if !info.complete {
             // We push the waiter on to the `waiters` list. It can be accessed inside
@@ -276,7 +275,7 @@ impl<D: DepKind> QueryLatch<D> {
 
     /// Removes a single waiter from the list of waiters.
     /// This is used to break query cycles.
-    fn extract_waiter(&self, waiter: usize) -> Lrc<QueryWaiter<D>> {
+    fn extract_waiter(&self, waiter: usize) -> Arc<QueryWaiter<D>> {
         let mut info = self.info.lock();
         debug_assert!(!info.complete);
         // Remove the waiter from the list of waiters
@@ -428,7 +427,7 @@ where
 fn remove_cycle<D: DepKind>(
     query_map: &QueryMap<D>,
     jobs: &mut Vec<QueryJobId>,
-    wakelist: &mut Vec<Lrc<QueryWaiter<D>>>,
+    wakelist: &mut Vec<Arc<QueryWaiter<D>>>,
 ) -> bool {
     let mut visited = FxHashSet::default();
     let mut stack = Vec::new();
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 0e9d74480a9..7b590d16d8c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4269,7 +4269,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ExprKind::ConstBlock(ref ct) => {
                 self.resolve_anon_const(ct, AnonConstKind::InlineConst);
             }
-            ExprKind::Index(ref elem, ref idx) => {
+            ExprKind::Index(ref elem, ref idx, _) => {
                 self.resolve_expr(elem, Some(expr));
                 self.visit_expr(idx);
             }
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 4811bb2c354..96a118e590f 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -248,9 +248,9 @@ fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option<Sym
     })
 }
 
-fn sort_by_words(name: &str) -> String {
+fn sort_by_words(name: &str) -> Vec<&str> {
     let mut split_words: Vec<&str> = name.split('_').collect();
     // We are sorting primitive &strs and can use unstable sort here.
     split_words.sort_unstable();
-    split_words.join("_")
+    split_words
 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index eae13eb6302..4d85e2b6089 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2987,6 +2987,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         unsatisfied_const: bool,
     ) {
         let body_def_id = obligation.cause.body_id;
+        let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } =
+            obligation.cause.code()
+        {
+            *rhs_span
+        } else {
+            span
+        };
+
         // Try to report a help message
         if is_fn_trait
             && let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 46c31c77613..32b4b4eb264 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2854,7 +2854,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         err.note("all local variables must have a statically known size");
                     }
                     Some(Node::Local(hir::Local {
-                        init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }),
+                        init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
                         ..
                     })) => {
                         // When encountering an assignment of an unsized trait, like
@@ -3953,9 +3953,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
     ) {
-        // We can only suggest the slice coersion for function arguments since the suggestion
-        // would make no sense in turbofish or call
-        let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
+        // We can only suggest the slice coersion for function and binary operation arguments,
+        // since the suggestion would make no sense in turbofish or call
+        let (ObligationCauseCode::BinOp { .. }
+        | ObligationCauseCode::FunctionArgumentObligation { .. }) = obligation.cause.code()
+        else {
             return;
         };
 
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index a5ec979ccd9..137bd9c9451 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -800,7 +800,7 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
         && parent.span.ctxt() == e.span.ctxt()
     {
         match parent.kind {
-            ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _)
+            ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
                 if child.hir_id == e.hir_id => true,
             ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
             _ => false,
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 83445c7a0ca..57df5683c9d 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -221,7 +221,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool {
     match e.kind {
         Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),
         Path(_) => true,
-        Field(inner, _) | Index(inner, _) => is_mutated_static(inner),
+        Field(inner, _) | Index(inner, _, _) => is_mutated_static(inner),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 01a7c497cbe..f507f45d5bb 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -254,7 +254,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
                 // Checking for slice indexing
                 let parent_id = map.parent_id(expr.hir_id);
                 if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id);
-                if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind;
+                if let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind;
                 if let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr);
                 if let Ok(index_value) = index_value.try_into();
                 if index_value < max_suggested_slice;
diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
index 22c14d9b04d..4f4f571773f 100644
--- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
             return;
         }
 
-        if let ExprKind::Index(array, index) = &expr.kind {
+        if let ExprKind::Index(array, index, _) = &expr.kind {
             let note = "the suggestion might not be applicable in constant blocks";
             let ty = cx.typeck_results().expr_ty(array).peel_refs();
             if let Some(range) = higher::Range::hir(index) {
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index 7d1f8ef29c8..d3fd0e8639e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -60,8 +60,8 @@ pub(super) fn check<'tcx>(
                     o.and_then(|(lhs, rhs)| {
                         let rhs = fetch_cloned_expr(rhs);
                         if_chain! {
-                            if let ExprKind::Index(base_left, idx_left) = lhs.kind;
-                            if let ExprKind::Index(base_right, idx_right) = rhs.kind;
+                            if let ExprKind::Index(base_left, idx_left, _) = lhs.kind;
+                            if let ExprKind::Index(base_right, idx_right, _) = rhs.kind;
                             if let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left));
                             if get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some();
                             if let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts);
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 2c20e9e8693..c4af46b8fd3 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
 
         if_chain! {
             // an index op
-            if let ExprKind::Index(seqexpr, idx) = expr.kind;
+            if let ExprKind::Index(seqexpr, idx, _) = expr.kind;
             if !self.check(idx, seqexpr, expr);
             then {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 7da9121fbb3..dd77c69ef88 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -162,7 +162,7 @@ fn never_loop_expr<'tcx>(
         ExprKind::Binary(_, e1, e2)
         | ExprKind::Assign(e1, e2, _)
         | ExprKind::AssignOp(_, e1, e2)
-        | ExprKind::Index(e1, e2) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
+        | ExprKind::Index(e1, e2, _) => never_loop_expr_all(cx, &mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
         ExprKind::Loop(b, _, _, _) => {
             // Break can come from the inner loop so remove them.
             absorb_break(never_loop_block(cx, b, ignore_ids, main_loop_id))
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
index 8019f906aca..5153070cfe6 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -113,7 +113,7 @@ fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExp
 
             // Shouldn't have side effects, but there's no way to trace which field is used. So forget which fields have
             // already been seen.
-            ExprKind::Index(base, idx) if !idx.can_have_side_effects() => {
+            ExprKind::Index(base, idx, _) if !idx.can_have_side_effects() => {
                 can_move = false;
                 fields.clear();
                 e = base;
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 2b9def1a688..201bb56efcd 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -204,7 +204,7 @@ fn find_stripping<'tcx>(
             if_chain! {
                 if is_ref_str(self.cx, ex);
                 let unref = peel_ref(ex);
-                if let ExprKind::Index(indexed, index) = &unref.kind;
+                if let ExprKind::Index(indexed, index, _) = &unref.kind;
                 if let Some(higher::Range { start, end, .. }) = higher::Range::hir(index);
                 if let ExprKind::Path(path) = &indexed.kind;
                 if self.cx.qpath_res(path, ex.hir_id) == self.target;
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs b/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs
index 89dcac4d849..bd53ebd48c8 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_on_vec_items.rs
@@ -12,7 +12,7 @@ use super::MATCH_ON_VEC_ITEMS;
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
     if_chain! {
         if let Some(idx_expr) = is_vec_indexing(cx, scrutinee);
-        if let ExprKind::Index(vec, idx) = idx_expr.kind;
+        if let ExprKind::Index(vec, idx, _) = idx_expr.kind;
 
         then {
             // FIXME: could be improved to suggest surrounding every pattern with Some(_),
@@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>) {
 
 fn is_vec_indexing<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
     if_chain! {
-        if let ExprKind::Index(array, index) = expr.kind;
+        if let ExprKind::Index(array, index, _) = expr.kind;
         if is_vector(cx, array);
         if !is_full_range(cx, index);
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
index ce7f9997b5a..ac7bc9bcca4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
@@ -12,7 +12,7 @@ use super::FILTER_NEXT;
 fn path_to_local(expr: &hir::Expr<'_>) -> Option<hir::HirId> {
     match expr.kind {
         hir::ExprKind::Field(f, _) => path_to_local(f),
-        hir::ExprKind::Index(recv, _) => path_to_local(recv),
+        hir::ExprKind::Index(recv, _, _) => path_to_local(recv),
         hir::ExprKind::Path(hir::QPath::Resolved(
             _,
             hir::Path {
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs
index e2029da8081..8f885e9f729 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_next_slice.rs
@@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, cal
     if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {
         // caller is a Slice
         if_chain! {
-            if let hir::ExprKind::Index(caller_var, index_expr) = &caller_expr.kind;
+            if let hir::ExprKind::Index(caller_var, index_expr, _) = &caller_expr.kind;
             if let Some(higher::Range { start: Some(start_expr), end: None, limits: ast::RangeLimits::HalfOpen })
                 = higher::Range::hir(index_expr);
             if let hir::ExprKind::Lit(start_lit) = &start_expr.kind;
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index 57ec3a1f1e6..367cd6bd413 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -239,7 +239,7 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
         | ExprKind::MethodCall(..)
         | ExprKind::Call(_, _)
         | ExprKind::Assign(..)
-        | ExprKind::Index(_, _)
+        | ExprKind::Index(..)
         | ExprKind::Repeat(_, _)
         | ExprKind::Struct(_, _, _) => {
             walk_expr(vis, expr);
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 46457400abc..f6b87b071b9 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -119,7 +119,7 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
     | ExprKind::Call(i, _)
     | ExprKind::Cast(i, _)
     | ExprKind::Type(i, _)
-    | ExprKind::Index(i, _) = inner.kind
+    | ExprKind::Index(i, _, _) = inner.kind
     {
         if matches!(
             i.kind,
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index e6d3e72d1e6..5f2a324b05f 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -160,7 +160,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match peel_blocks(expr).kind {
         ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
         ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)),
-        ExprKind::Index(a, b) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
+        ExprKind::Index(a, b, _) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
         ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)),
         ExprKind::Repeat(inner, _)
         | ExprKind::Cast(inner, _)
@@ -263,7 +263,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
         return None;
     }
     match expr.kind {
-        ExprKind::Index(a, b) => Some(vec![a, b]),
+        ExprKind::Index(a, b, _) => Some(vec![a, b]),
         ExprKind::Binary(ref binop, a, b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {
             Some(vec![a, b])
         },
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index a70692d8ff8..243192385c2 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -438,7 +438,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
 
                             dereferenced_expr = parent_expr;
                         },
-                        ExprKind::Index(e, _) if ptr::eq(&**e, cur_expr) => {
+                        ExprKind::Index(e, _, _) if ptr::eq(&**e, cur_expr) => {
                             // `e[i]` => desugared to `*Index::index(&e, i)`,
                             // meaning `e` must be referenced.
                             // no need to go further up since a method call is involved now.
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 42299d8d42f..8009b00b4b9 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -695,7 +695,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
                         }
                     },
                     // Indexing is fine for currently supported types.
-                    ExprKind::Index(e, _) if e.hir_id == child_id => (),
+                    ExprKind::Index(e, _, _) if e.hir_id == child_id => (),
                     _ => set_skip_flag(),
                 },
                 _ => set_skip_flag(),
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 8277ce724d4..4abfa0fc35c 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
         if_chain! {
             if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind;
             if addressee.span.ctxt() == ctxt;
-            if let ExprKind::Index(indexed, range) = addressee.kind;
+            if let ExprKind::Index(indexed, range, _) = addressee.kind;
             if is_type_lang_item(cx, cx.typeck_results().expr_ty_adjusted(range), LangItem::RangeFull);
             then {
                 let (expr_ty, expr_ref_count) = peel_mid_ty_refs(cx.typeck_results().expr_ty(expr));
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 4d45091f4b5..76f463fff7d 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
                     );
                 }
             },
-            ExprKind::Index(target, _idx) => {
+            ExprKind::Index(target, _idx, _) => {
                 let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
                 if e_ty.is_str() || is_type_lang_item(cx, e_ty, LangItem::String) {
                     span_lint(
@@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
 
             // Find string::as_bytes
             if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind;
-            if let ExprKind::Index(left, right) = args.kind;
+            if let ExprKind::Index(left, right, _) = args.kind;
             let (method_names, expressions, _) = method_calls(left, 1);
             if method_names.len() == 1;
             if expressions.len() == 1;
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
index e2cdc48b583..23d6e2a845f 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -572,7 +572,7 @@ fn ident_difference_expr_with_base_location(
         | (AddrOf(_, _, _), AddrOf(_, _, _))
         | (Path(_, _), Path(_, _))
         | (Range(_, _, _), Range(_, _, _))
-        | (Index(_, _), Index(_, _))
+        | (Index(_, _, _), Index(_, _, _))
         | (Field(_, _), Field(_, _))
         | (AssignOp(_, _, _), AssignOp(_, _, _))
         | (Assign(_, _, _), Assign(_, _, _))
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 98158ed0aee..548fabb8b73 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -86,8 +86,8 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
     let mut applicability = Applicability::MachineApplicable;
 
     if !can_mut_borrow_both(cx, e1, e2) {
-        if let ExprKind::Index(lhs1, idx1) = e1.kind
-            && let ExprKind::Index(lhs2, idx2) = e2.kind
+        if let ExprKind::Index(lhs1, idx1, _) = e1.kind
+            && let ExprKind::Index(lhs2, idx2, _) = e2.kind
             && eq_expr_value(cx, lhs1, lhs2)
             && e1.span.ctxt() == ctxt
             && e2.span.ctxt() == ctxt
diff --git a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
index 3766b8f8ed1..b6b653f6610 100644
--- a/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
+++ b/src/tools/clippy/clippy_lints/src/temporary_assignment.rs
@@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let ExprKind::Assign(target, ..) = &expr.kind {
             let mut base = target;
-            while let ExprKind::Field(f, _) | ExprKind::Index(f, _) = &base.kind {
+            while let ExprKind::Field(f, _) | ExprKind::Index(f, _, _) = &base.kind {
                 base = f;
             }
             if is_temporary(base) && !is_adjusted(cx, base) {
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 7eec6982092..78ad52d8a87 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -103,11 +103,11 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &
         // Fix #11100
         && tys.iter().all_equal()
         && let Some(locals) = (match first.kind {
-            ExprKind::Index(_, _) => elements
+            ExprKind::Index(..) => elements
                 .iter()
                 .enumerate()
                 .map(|(i, i_expr)| -> Option<&'tcx Expr<'tcx>> {
-                    if let ExprKind::Index(lhs, index) = i_expr.kind
+                    if let ExprKind::Index(lhs, index, _) = i_expr.kind
                         && let ExprKind::Lit(lit) = index.kind
                         && let LitKind::Int(val, _) = lit.node
                     {
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 6b51974d739..f02c33cc674 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -526,7 +526,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 self.ident(field_name);
                 self.expr(object);
             },
-            ExprKind::Index(object, index) => {
+            ExprKind::Index(object, index, _) => {
                 bind!(self, object, index);
                 kind!("Index({object}, {index})");
                 self.expr(object);
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index 1d4fc24eb6c..3fa51216c77 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -88,7 +88,7 @@ impl VecPushSearcher {
                     let mut last_place = parent;
                     while let Some(parent) = get_parent_expr(cx, last_place) {
                         if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..))
-                            || matches!(parent.kind, ExprKind::Index(e, _) if e.hir_id == last_place.hir_id)
+                            || matches!(parent.kind, ExprKind::Index(e, _, _) if e.hir_id == last_place.hir_id)
                         {
                             last_place = parent;
                         } else {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 7e42924603a..2d0d6f559ad 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -178,7 +178,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
         (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
         (Continue(ll), Continue(rl)) => eq_label(ll, rl),
-        (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2), Index(r1, r2)) => eq_expr(l1, r1) && eq_expr(l2, r2),
+        (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => eq_expr(l1, r1) && eq_expr(l2, r2),
         (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
         (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
         (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 89f8a65c5ae..60fab1ec41a 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -163,7 +163,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
         ) => (Pat::Str("unsafe"), Pat::Str("}")),
         ExprKind::Block(_, None) => (Pat::Str("{"), Pat::Str("}")),
         ExprKind::Field(e, name) => (expr_search_pat(tcx, e).0, Pat::Sym(name.name)),
-        ExprKind::Index(e, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
+        ExprKind::Index(e, _, _) => (expr_search_pat(tcx, e).0, Pat::Str("]")),
         ExprKind::Path(ref path) => qpath_search_pat(path),
         ExprKind::AddrOf(_, _, e) => (Pat::Str("&"), expr_search_pat(tcx, e).1),
         ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str("break"), Pat::Str("break")),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index f19e09a18ec..d38e3f1ae76 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -394,7 +394,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     }
                 }
             },
-            ExprKind::Index(arr, index) => self.index(arr, index),
+            ExprKind::Index(arr, index, _) => self.index(arr, index),
             ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))),
             ExprKind::Field(local_expr, ref field) => {
                 let result = self.expr(local_expr);
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 3c969572b8e..0bcefba75a7 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -185,7 +185,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
                         .type_dependent_def_id(e.hir_id)
                         .map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));
                 },
-                ExprKind::Index(_, e) => {
+                ExprKind::Index(_, e, _) => {
                     let ty = self.cx.typeck_results().expr_ty_adjusted(e);
                     if is_copy(self.cx, ty) && !ty.is_ref() {
                         self.eagerness |= NoChange;
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 85b3b005f93..fdc35cd4ddf 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -299,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => {
                 l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp)
             },
-            (&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
+            (&ExprKind::Index(la, li, _), &ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
             (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
                 self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
             },
@@ -730,7 +730,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_expr(e);
                 self.hash_name(f.name);
             },
-            ExprKind::Index(a, i) => {
+            ExprKind::Index(a, i, _) => {
                 self.hash_expr(a);
                 self.hash_expr(i);
             },
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index cf30930b76e..4cd8a8c3325 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -735,7 +735,7 @@ fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'
     let mut result = vec![];
     let root = loop {
         match e.kind {
-            ExprKind::Index(ep, _) | ExprKind::Field(ep, _) => {
+            ExprKind::Index(ep, _, _) | ExprKind::Field(ep, _) => {
                 result.push(e);
                 e = ep;
             },
@@ -782,7 +782,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
                     return true;
                 }
             },
-            (ExprKind::Index(_, i1), ExprKind::Index(_, i2)) => {
+            (ExprKind::Index(_, i1, _), ExprKind::Index(_, i2, _)) => {
                 if !eq_expr_value(cx, i1, i2) {
                     return false;
                 }
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 45b5483e323..0669ea72eb3 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -31,7 +31,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
     let certainty = match &expr.kind {
         ExprKind::Unary(_, expr)
         | ExprKind::Field(expr, _)
-        | ExprKind::Index(expr, _)
+        | ExprKind::Index(expr, _, _)
         | ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr),
 
         ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 09f447b27eb..f83988a6e32 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -329,7 +329,7 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                         && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
                 ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (),
                 ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),
-                ExprKind::Index(base, _)
+                ExprKind::Index(base, _, _)
                     if matches!(
                         self.cx.typeck_results().expr_ty(base).peel_refs().kind(),
                         ty::Slice(_) | ty::Array(..)
@@ -629,7 +629,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
                     helper(typeck, true, arg, f)?;
                 }
             },
-            ExprKind::Index(borrowed, consumed)
+            ExprKind::Index(borrowed, consumed, _)
             | ExprKind::Assign(borrowed, consumed, _)
             | ExprKind::AssignOp(_, borrowed, consumed) => {
                 helper(typeck, false, borrowed, f)?;
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index e929091b396..75e4b5f8466 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::{Mutability, RetagKind};
 use rustc_middle::ty::{
     self,
-    layout::{HasParamEnv, LayoutOf},
+    layout::HasParamEnv,
     Ty,
 };
 use rustc_target::abi::{Abi, Align, Size};
@@ -993,8 +993,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         // We have to turn the place into a pointer to use the usual retagging logic.
         // (The pointer type does not matter, so we use a raw pointer.)
-        let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?;
-        let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout);
+        let ptr = this.mplace_to_ref(place)?;
         // Reborrow it. With protection! That is the entire point.
         let new_perm = NewPermission::Uniform {
             perm: Permission::Unique,
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index b2dbe8a70f0..d30745b3b61 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -7,7 +7,7 @@ use rustc_middle::{
     mir::{Mutability, RetagKind},
     ty::{
         self,
-        layout::{HasParamEnv, LayoutOf},
+        layout::HasParamEnv,
         Ty,
     },
 };
@@ -488,8 +488,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         // We have to turn the place into a pointer to use the usual retagging logic.
         // (The pointer type does not matter, so we use a raw pointer.)
-        let ptr_layout = this.layout_of(Ty::new_mut_ptr(this.tcx.tcx, place.layout.ty))?;
-        let ptr = ImmTy::from_immediate(place.to_ref(this), ptr_layout);
+        let ptr = this.mplace_to_ref(place)?;
         // Reborrow it. With protection! That is the entire point.
         let new_perm = NewPermission {
             initial_state: Permission::new_active(),
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 739afb4e0ac..c3c07f310bf 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -256,7 +256,7 @@ pub(crate) fn format_expr(
             shape,
             SeparatorPlace::Back,
         ),
-        ast::ExprKind::Index(ref expr, ref index) => {
+        ast::ExprKind::Index(ref expr, ref index, _) => {
             rewrite_index(&**expr, &**index, context, shape)
         }
         ast::ExprKind::Repeat(ref expr, ref repeats) => rewrite_pair(
@@ -1342,7 +1342,7 @@ pub(crate) fn is_simple_expr(expr: &ast::Expr) -> bool {
         | ast::ExprKind::Field(ref expr, _)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Unary(_, ref expr) => is_simple_expr(expr),
-        ast::ExprKind::Index(ref lhs, ref rhs) => is_simple_expr(lhs) && is_simple_expr(rhs),
+        ast::ExprKind::Index(ref lhs, ref rhs, _) => is_simple_expr(lhs) && is_simple_expr(rhs),
         ast::ExprKind::Repeat(ref lhs, ref rhs) => {
             is_simple_expr(lhs) && is_simple_expr(&*rhs.value)
         }
diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs
index aac5e59b860..4c37116f120 100644
--- a/src/tools/rustfmt/src/matches.rs
+++ b/src/tools/rustfmt/src/matches.rs
@@ -594,7 +594,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
         ast::ExprKind::AddrOf(_, _, ref expr)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Index(ref expr, _)
+        | ast::ExprKind::Index(ref expr, _, _)
         | ast::ExprKind::Cast(ref expr, _) => can_flatten_block_around_this(expr),
         _ => false,
     }
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index 890a05b8c82..4fc5a9b6896 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -441,7 +441,7 @@ pub(crate) fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
         | ast::ExprKind::Assign(ref e, _, _)
         | ast::ExprKind::AssignOp(_, ref e, _)
         | ast::ExprKind::Field(ref e, _)
-        | ast::ExprKind::Index(ref e, _)
+        | ast::ExprKind::Index(ref e, _, _)
         | ast::ExprKind::Range(Some(ref e), _, _)
         | ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
         _ => e,
@@ -479,7 +479,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Match(..) => repr.contains('\n'),
         ast::ExprKind::Paren(ref expr)
         | ast::ExprKind::Binary(_, _, ref expr)
-        | ast::ExprKind::Index(_, ref expr)
+        | ast::ExprKind::Index(_, ref expr, _)
         | ast::ExprKind::Unary(_, ref expr)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 44c7c07d3a0..930b7408390 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 const ISSUES_ENTRY_LIMIT: usize = 1893;
-const ROOT_ENTRY_LIMIT: usize = 873;
+const ROOT_ENTRY_LIMIT: usize = 866;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/ui/array-slice-vec/slice-2.stderr b/tests/ui/array-slice-vec/slice-2.stderr
index 561feb90f0a..b122b46914c 100644
--- a/tests/ui/array-slice-vec/slice-2.stderr
+++ b/tests/ui/array-slice-vec/slice-2.stderr
@@ -1,26 +1,26 @@
 error[E0608]: cannot index into a value of type `Foo`
-  --> $DIR/slice-2.rs:7:6
+  --> $DIR/slice-2.rs:7:7
    |
 LL |     &x[..];
-   |      ^^^^^
+   |       ^^^^
 
 error[E0608]: cannot index into a value of type `Foo`
-  --> $DIR/slice-2.rs:8:6
+  --> $DIR/slice-2.rs:8:7
    |
 LL |     &x[Foo..];
-   |      ^^^^^^^^
+   |       ^^^^^^^
 
 error[E0608]: cannot index into a value of type `Foo`
-  --> $DIR/slice-2.rs:9:6
+  --> $DIR/slice-2.rs:9:7
    |
 LL |     &x[..Foo];
-   |      ^^^^^^^^
+   |       ^^^^^^^
 
 error[E0608]: cannot index into a value of type `Foo`
-  --> $DIR/slice-2.rs:10:6
+  --> $DIR/slice-2.rs:10:7
    |
 LL |     &x[Foo..Foo];
-   |      ^^^^^^^^^^^
+   |       ^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/borrowck/suggest-local-var-for-vector.stderr b/tests/ui/borrowck/suggest-local-var-for-vector.stderr
index ea92d76b4ec..c8d00f7b222 100644
--- a/tests/ui/borrowck/suggest-local-var-for-vector.stderr
+++ b/tests/ui/borrowck/suggest-local-var-for-vector.stderr
@@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
    |
 LL |     vec[vec.len() - 1] = 123;
    |     ----^^^-----------
-   |     |   |
-   |     |   immutable borrow occurs here
+   |     |  ||
+   |     |  |immutable borrow occurs here
+   |     |  mutable borrow later used here
    |     mutable borrow occurs here
-   |     mutable borrow later used here
    |
 help: try adding a local storing this...
   --> $DIR/suggest-local-var-for-vector.rs:3:9
@@ -14,10 +14,10 @@ help: try adding a local storing this...
 LL |     vec[vec.len() - 1] = 123;
    |         ^^^^^^^^^
 help: ...and then using that local here
-  --> $DIR/suggest-local-var-for-vector.rs:3:5
+  --> $DIR/suggest-local-var-for-vector.rs:3:8
    |
 LL |     vec[vec.len() - 1] = 123;
-   |     ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr b/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr
index 6007beb7753..368d728101c 100644
--- a/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr
+++ b/tests/ui/borrowck/suggest-storing-local-var-for-vector.stderr
@@ -3,10 +3,10 @@ error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mu
    |
 LL |     vec[vec.len() - 1] = 123;
    |     ----^^^-----------
-   |     |   |
-   |     |   immutable borrow occurs here
+   |     |  ||
+   |     |  |immutable borrow occurs here
+   |     |  mutable borrow later used here
    |     mutable borrow occurs here
-   |     mutable borrow later used here
    |
 help: try adding a local storing this...
   --> $DIR/suggest-storing-local-var-for-vector.rs:3:9
@@ -14,10 +14,10 @@ help: try adding a local storing this...
 LL |     vec[vec.len() - 1] = 123;
    |         ^^^^^^^^^
 help: ...and then using that local here
-  --> $DIR/suggest-storing-local-var-for-vector.rs:3:5
+  --> $DIR/suggest-storing-local-var-for-vector.rs:3:8
    |
 LL |     vec[vec.len() - 1] = 123;
-   |     ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr b/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr
index efd63a08aae..e122977b9f2 100644
--- a/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr
+++ b/tests/ui/borrowck/two-phase-nonrecv-autoref.base.stderr
@@ -50,42 +50,42 @@ error[E0502]: cannot borrow `i` as immutable because it is also borrowed as muta
    |
 LL |     i[i[3]] = 4;
    |     --^----
-   |     | |
-   |     | immutable borrow occurs here
+   |     |||
+   |     ||immutable borrow occurs here
+   |     |mutable borrow later used here
    |     mutable borrow occurs here
-   |     mutable borrow later used here
    |
 help: try adding a local storing this...
-  --> $DIR/two-phase-nonrecv-autoref.rs:132:7
+  --> $DIR/two-phase-nonrecv-autoref.rs:132:8
    |
 LL |     i[i[3]] = 4;
-   |       ^^^^
+   |        ^^^
 help: ...and then using that local here
-  --> $DIR/two-phase-nonrecv-autoref.rs:132:5
+  --> $DIR/two-phase-nonrecv-autoref.rs:132:6
    |
 LL |     i[i[3]] = 4;
-   |     ^^^^^^^
+   |      ^^^^^^
 
 error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable
   --> $DIR/two-phase-nonrecv-autoref.rs:138:7
    |
 LL |     i[i[3]] = i[4];
    |     --^----
-   |     | |
-   |     | immutable borrow occurs here
+   |     |||
+   |     ||immutable borrow occurs here
+   |     |mutable borrow later used here
    |     mutable borrow occurs here
-   |     mutable borrow later used here
    |
 help: try adding a local storing this...
-  --> $DIR/two-phase-nonrecv-autoref.rs:138:7
+  --> $DIR/two-phase-nonrecv-autoref.rs:138:8
    |
 LL |     i[i[3]] = i[4];
-   |       ^^^^
+   |        ^^^
 help: ...and then using that local here
-  --> $DIR/two-phase-nonrecv-autoref.rs:138:5
+  --> $DIR/two-phase-nonrecv-autoref.rs:138:6
    |
 LL |     i[i[3]] = i[4];
-   |     ^^^^^^^
+   |      ^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr
index cee4dfda2c9..f51f305ac38 100644
--- a/tests/ui/consts/issue-94675.stderr
+++ b/tests/ui/consts/issue-94675.stderr
@@ -7,10 +7,10 @@ LL |         self.bar[0] = baz.len();
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/issue-94675.rs:11:9
+  --> $DIR/issue-94675.rs:11:17
    |
 LL |         self.bar[0] = baz.len();
-   |         ^^^^^^^^^^^
+   |                 ^^^
    |
 note: impl defined here, but it is not `const`
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
diff --git a/tests/ui/dst/issue-113447.fixed b/tests/ui/dst/issue-113447.fixed
new file mode 100644
index 00000000000..536f680f697
--- /dev/null
+++ b/tests/ui/dst/issue-113447.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+
+pub struct Bytes;
+
+impl Bytes {
+    pub fn as_slice(&self) -> &[u8] {
+        todo!()
+    }
+}
+
+impl PartialEq<[u8]> for Bytes {
+    fn eq(&self, other: &[u8]) -> bool {
+        self.as_slice() == other
+    }
+}
+
+impl PartialEq<Bytes> for &[u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == **self
+    }
+}
+
+fn main() {
+    let _ = &[0u8] == &[0xAA][..]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
+}
diff --git a/tests/ui/dst/issue-113447.rs b/tests/ui/dst/issue-113447.rs
new file mode 100644
index 00000000000..c10a4f2ff8e
--- /dev/null
+++ b/tests/ui/dst/issue-113447.rs
@@ -0,0 +1,25 @@
+// run-rustfix
+
+pub struct Bytes;
+
+impl Bytes {
+    pub fn as_slice(&self) -> &[u8] {
+        todo!()
+    }
+}
+
+impl PartialEq<[u8]> for Bytes {
+    fn eq(&self, other: &[u8]) -> bool {
+        self.as_slice() == other
+    }
+}
+
+impl PartialEq<Bytes> for &[u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == **self
+    }
+}
+
+fn main() {
+    let _ = &[0u8] == [0xAA]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
+}
diff --git a/tests/ui/dst/issue-113447.stderr b/tests/ui/dst/issue-113447.stderr
new file mode 100644
index 00000000000..240553a675b
--- /dev/null
+++ b/tests/ui/dst/issue-113447.stderr
@@ -0,0 +1,25 @@
+error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]`
+  --> $DIR/issue-113447.rs:24:20
+   |
+LL |     let _ = &[0u8] == [0xAA];
+   |                    ^^ no implementation for `&[u8; 1] == [{integer}; 1]`
+   |
+   = help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]`
+   = help: the following other types implement trait `PartialEq<Rhs>`:
+             <[A; N] as PartialEq<[B; N]>>
+             <[A; N] as PartialEq<[B]>>
+             <[A; N] as PartialEq<&[B]>>
+             <[A; N] as PartialEq<&mut [B]>>
+             <[T] as PartialEq<Vec<U, A>>>
+             <[A] as PartialEq<[B]>>
+             <[B] as PartialEq<[A; N]>>
+             <&[u8] as PartialEq<Bytes>>
+           and 4 others
+help: convert the array to a `&[u8]` slice instead
+   |
+LL |     let _ = &[0u8] == &[0xAA][..];
+   |                       +      ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/error-codes/E0608.stderr b/tests/ui/error-codes/E0608.stderr
index 3aec509934b..f23f9977ba0 100644
--- a/tests/ui/error-codes/E0608.stderr
+++ b/tests/ui/error-codes/E0608.stderr
@@ -1,8 +1,8 @@
 error[E0608]: cannot index into a value of type `u8`
-  --> $DIR/E0608.rs:2:5
+  --> $DIR/E0608.rs:2:8
    |
 LL |     0u8[2];
-   |     ^^^^^^
+   |        ^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/index-bot.rs b/tests/ui/indexing/index-bot.rs
index e69c4019f61..e69c4019f61 100644
--- a/tests/ui/index-bot.rs
+++ b/tests/ui/indexing/index-bot.rs
diff --git a/tests/ui/index-bot.stderr b/tests/ui/indexing/index-bot.stderr
index b5d78297505..bf231c92cad 100644
--- a/tests/ui/index-bot.stderr
+++ b/tests/ui/indexing/index-bot.stderr
@@ -1,8 +1,8 @@
 error[E0608]: cannot index into a value of type `!`
-  --> $DIR/index-bot.rs:2:5
+  --> $DIR/index-bot.rs:2:13
    |
 LL |     (return)[0];
-   |     ^^^^^^^^^^^
+   |             ^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/index-help.rs b/tests/ui/indexing/index-help.rs
index 66571ec41a0..66571ec41a0 100644
--- a/tests/ui/index-help.rs
+++ b/tests/ui/indexing/index-help.rs
diff --git a/tests/ui/index-help.stderr b/tests/ui/indexing/index-help.stderr
index e020d029875..e020d029875 100644
--- a/tests/ui/index-help.stderr
+++ b/tests/ui/indexing/index-help.stderr
diff --git a/tests/ui/index_message.rs b/tests/ui/indexing/index_message.rs
index 88b848d6f85..88b848d6f85 100644
--- a/tests/ui/index_message.rs
+++ b/tests/ui/indexing/index_message.rs
diff --git a/tests/ui/index_message.stderr b/tests/ui/indexing/index_message.stderr
index 56d1d70809d..80f2bd52314 100644
--- a/tests/ui/index_message.stderr
+++ b/tests/ui/indexing/index_message.stderr
@@ -1,8 +1,8 @@
 error[E0608]: cannot index into a value of type `({integer},)`
-  --> $DIR/index_message.rs:3:13
+  --> $DIR/index_message.rs:3:14
    |
 LL |     let _ = z[0];
-   |             ^^^^ help: to access tuple elements, use: `z.0`
+   |              ^^^ help: to access tuple elements, use: `.0`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/indexing-requires-a-uint.rs b/tests/ui/indexing/indexing-requires-a-uint.rs
index dbe9b44a138..dbe9b44a138 100644
--- a/tests/ui/indexing-requires-a-uint.rs
+++ b/tests/ui/indexing/indexing-requires-a-uint.rs
diff --git a/tests/ui/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
index 7a741cfc7de..7a741cfc7de 100644
--- a/tests/ui/indexing-requires-a-uint.stderr
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
diff --git a/tests/ui/indexing/indexing-spans-caller-location.rs b/tests/ui/indexing/indexing-spans-caller-location.rs
new file mode 100644
index 00000000000..2652f00211d
--- /dev/null
+++ b/tests/ui/indexing/indexing-spans-caller-location.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+// Regression test for https://github.com/rust-lang/rust/issues/114388
+
+#[track_caller]
+fn caller_line() -> u32 {
+    std::panic::Location::caller().line()
+}
+
+fn main() {
+    let prev_line = caller_line(); // first line
+    (A { prev_line }) // second line
+    [0]; // third line
+}
+
+struct A {
+    prev_line: u32,
+}
+impl std::ops::Index<usize> for A {
+    type Output = ();
+
+    fn index(&self, _idx: usize) -> &() {
+        // Use the relative number to make it resistent to header changes.
+        assert_eq!(caller_line(), self.prev_line + 2);
+        &()
+    }
+}
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
index 69c7491b2af..a0024c0920f 100644
--- a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
+++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
@@ -1,3 +1,3 @@
-thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:6:
+thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
 byte index 1 is out of bounds of ``
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/invalid/issue-114435-layout-type-err.rs b/tests/ui/invalid/issue-114435-layout-type-err.rs
new file mode 100644
index 00000000000..a2d40593687
--- /dev/null
+++ b/tests/ui/invalid/issue-114435-layout-type-err.rs
@@ -0,0 +1,44 @@
+// build-fail
+// compile-flags: --crate-type lib -Cdebuginfo=2
+// error-pattern: the type has an unknown layout
+
+#![recursion_limit = "10"]
+macro_rules! link {
+    ($outer:ident, $inner:ident) => {
+        struct $outer($inner);
+        impl $outer {
+            fn new() -> $outer {
+                $outer($inner::new())
+            }
+        }
+        impl std::ops::Deref for $outer {
+            type Target = $inner;
+            fn deref(&self) -> &$inner {
+                &self.0
+            }
+        }
+    };
+}
+
+struct Bottom;
+
+impl Bottom {
+    fn new() -> Bottom {
+        Bottom
+    }
+}
+
+
+link!(A, B);
+link!(B, C);
+link!(C, D);
+link!(D, E);
+link!(E, F);
+link!(F, G);
+link!(G, H);
+link!(H, I);
+link!(I, J);
+link!(J, K);
+link!(K, Bottom);
+
+fn main() { }
diff --git a/tests/ui/invalid/issue-114435-layout-type-err.stderr b/tests/ui/invalid/issue-114435-layout-type-err.stderr
new file mode 100644
index 00000000000..a2db74ff8bd
--- /dev/null
+++ b/tests/ui/invalid/issue-114435-layout-type-err.stderr
@@ -0,0 +1,8 @@
+error: reached the recursion limit finding the struct tail for `Bottom`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]`
+
+error: the type has an unknown layout
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/issues/issue-27842.stderr b/tests/ui/issues/issue-27842.stderr
index 83333aa0c47..b18fe1512b5 100644
--- a/tests/ui/issues/issue-27842.stderr
+++ b/tests/ui/issues/issue-27842.stderr
@@ -1,24 +1,24 @@
 error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
-  --> $DIR/issue-27842.rs:4:13
+  --> $DIR/issue-27842.rs:4:16
    |
 LL |     let _ = tup[0];
-   |             ^^^^^^ help: to access tuple elements, use: `tup.0`
+   |                ^^^ help: to access tuple elements, use: `.0`
 
 error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})`
-  --> $DIR/issue-27842.rs:9:13
+  --> $DIR/issue-27842.rs:9:16
    |
 LL |     let _ = tup[i];
-   |             ^^^^-^
+   |                ^-^
    |                 |
    |                 cannot access tuple elements at a variable index
    |
    = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
 
 error[E0608]: cannot index into a value of type `({integer},)`
-  --> $DIR/issue-27842.rs:14:13
+  --> $DIR/issue-27842.rs:14:16
    |
 LL |     let _ = tup[3];
-   |             ^^^^^^
+   |                ^^^
    |
    = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
 
diff --git a/tests/ui/issues/issue-40861.stderr b/tests/ui/issues/issue-40861.stderr
index 84e38b9bb05..9b6469d05e9 100644
--- a/tests/ui/issues/issue-40861.stderr
+++ b/tests/ui/issues/issue-40861.stderr
@@ -1,8 +1,8 @@
 error[E0608]: cannot index into a value of type `()`
-  --> $DIR/issue-40861.rs:4:5
+  --> $DIR/issue-40861.rs:4:7
    |
 LL |     ()[f(&[1.0])];
-   |     ^^^^^^^^^^^^^
+   |       ^^^^^^^^^^^
    |
    = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`)
 
diff --git a/tests/ui/lint/lint-unconditional-recursion.stderr b/tests/ui/lint/lint-unconditional-recursion.stderr
index 9d200a7898e..d75754bf9f9 100644
--- a/tests/ui/lint/lint-unconditional-recursion.stderr
+++ b/tests/ui/lint/lint-unconditional-recursion.stderr
@@ -139,7 +139,7 @@ error: function cannot return without recursing
 LL |     fn index(&self, x: usize) -> &Baz {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
 LL |         &self[x]
-   |          ------- recursive call site
+   |              --- recursive call site
    |
    = help: a `loop` may express intention better if this is on purpose
 
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
index e7da825ae36..b2d8a28d3c4 100644
--- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
@@ -5,8 +5,8 @@ const s: usize = 42;
 const s_s: usize = 42;
 
 fn main() {
-    let s = "rust"; //~ ERROR identifier pair considered confusable
-    let s_s = "rust2"; //~ ERROR identifier pair considered confusable
+    let s = "rust"; //~ ERROR found both
+    let s_s = "rust2"; //~ ERROR found both
     not_affected();
 }
 
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
index e9906c83d12..d1920f215e2 100644
--- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
@@ -1,11 +1,11 @@
-error: identifier pair considered confusable between `s` and `s`
+error: found both `s` and `s` as identifiers, which look alike
   --> $DIR/lint-confusable-idents.rs:8:9
    |
 LL | const s: usize = 42;
-   |       -- this is where the previous identifier occurred
+   |       -- other identifier used here
 ...
 LL |     let s = "rust";
-   |         ^
+   |         ^ this identifier can be confused with `s`
    |
 note: the lint level is defined here
   --> $DIR/lint-confusable-idents.rs:1:9
@@ -13,14 +13,14 @@ note: the lint level is defined here
 LL | #![deny(confusable_idents)]
    |         ^^^^^^^^^^^^^^^^^
 
-error: identifier pair considered confusable between `s_s` and `s_s`
+error: found both `s_s` and `s_s` as identifiers, which look alike
   --> $DIR/lint-confusable-idents.rs:9:9
    |
 LL | const s_s: usize = 42;
-   |       --- this is where the previous identifier occurred
+   |       --- other identifier used here
 ...
 LL |     let s_s = "rust2";
-   |         ^^^^^
+   |         ^^^^^ this identifier can be confused with `s_s`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr b/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr
index 22e7951dbe3..0bb486a8893 100644
--- a/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr
+++ b/tests/ui/moves/use_of_moved_value_clone_suggestions.stderr
@@ -8,7 +8,7 @@ LL |     (t, t)
    |      |
    |      value moved here
    |
-help: consider cloning the value if the performance cost is acceptable
+help: clone the value to increment its reference count
    |
 LL |     (t.clone(), t)
    |       ++++++++
diff --git a/tests/ui/span/suggestion-non-ascii.stderr b/tests/ui/span/suggestion-non-ascii.stderr
index b14632d4e1b..21f8bb62a0c 100644
--- a/tests/ui/span/suggestion-non-ascii.stderr
+++ b/tests/ui/span/suggestion-non-ascii.stderr
@@ -1,8 +1,8 @@
 error[E0608]: cannot index into a value of type `({integer},)`
-  --> $DIR/suggestion-non-ascii.rs:3:21
+  --> $DIR/suggestion-non-ascii.rs:3:24
    |
 LL |     println!("☃{}", tup[0]);
-   |                     ^^^^^^ help: to access tuple elements, use: `tup.0`
+   |                        ^^^ help: to access tuple elements, use: `.0`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr
index c55930da225..f81736245f3 100644
--- a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr
+++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr
@@ -38,10 +38,10 @@ LL |     let _c = unsafe { _ptr2.offset_from(_ptr1) };
    |              ++++++++      ~~~~~~~~~~~~~     +++
 
 error[E0608]: cannot index into a value of type `*const u32`
-  --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14
+  --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:19
    |
 LL |     let _d = _ptr1[5];
-   |              ^^^^^^^^
+   |                   ^^^
    |
 help: consider using `wrapping_add` or `add` for indexing into raw pointer
    |
diff --git a/tests/ui/typeck/issue-114423.rs b/tests/ui/typeck/issue-114423.rs
new file mode 100644
index 00000000000..da2dae1c46b
--- /dev/null
+++ b/tests/ui/typeck/issue-114423.rs
@@ -0,0 +1,15 @@
+struct RGB {
+    g: f64,
+    b: f64,
+}
+
+fn main() {
+    let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone());
+    //~^ ERROR cannot find value `e` in this scope
+    //~| ERROR cannot find value `e` in this scope
+    //~| ERROR mismatched types
+    let _ = RGB { r, g, b };
+    //~^ ERROR cannot find value `g` in this scope
+    //~| ERROR struct `RGB` has no field named `r`
+    //~| ERROR mismatched types
+}
diff --git a/tests/ui/typeck/issue-114423.stderr b/tests/ui/typeck/issue-114423.stderr
new file mode 100644
index 00000000000..c20a4391297
--- /dev/null
+++ b/tests/ui/typeck/issue-114423.stderr
@@ -0,0 +1,52 @@
+error[E0425]: cannot find value `e` in this scope
+  --> $DIR/issue-114423.rs:7:51
+   |
+LL |     let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone());
+   |                                                   ^ not found in this scope
+
+error[E0425]: cannot find value `e` in this scope
+  --> $DIR/issue-114423.rs:7:62
+   |
+LL |     let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone());
+   |                                                              ^ not found in this scope
+
+error[E0425]: cannot find value `g` in this scope
+  --> $DIR/issue-114423.rs:11:22
+   |
+LL |     let _ = RGB { r, g, b };
+   |                      ^ help: a local variable with a similar name exists: `b`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-114423.rs:7:50
+   |
+LL |     let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone());
+   |                                ---------------   ^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements
+   |                                |
+   |                                expected due to this
+   |
+   = note: expected tuple `(f32, f32, f32)`
+              found tuple `(f32, f32)`
+
+error[E0560]: struct `RGB` has no field named `r`
+  --> $DIR/issue-114423.rs:11:19
+   |
+LL |     let _ = RGB { r, g, b };
+   |                   ^ `RGB` does not have this field
+   |
+   = note: all struct fields are already assigned
+
+error[E0308]: mismatched types
+  --> $DIR/issue-114423.rs:11:25
+   |
+LL |     let _ = RGB { r, g, b };
+   |                         ^ expected `f64`, found `f32`
+   |
+help: you can convert an `f32` to an `f64`
+   |
+LL |     let _ = RGB { r, g, b: b.into() };
+   |                         ++  +++++++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0308, E0425, E0560.
+For more information about an error, try `rustc --explain E0308`.