about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs8
-rw-r--r--compiler/rustc_hir/src/hir.rs4
-rw-r--r--compiler/rustc_hir/src/intravisit.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs19
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs10
-rw-r--r--compiler/rustc_lint/src/array_into_iter.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs4
-rw-r--r--compiler/rustc_lint/src/internal.rs2
-rw-r--r--compiler/rustc_lint/src/methods.rs18
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs3
-rw-r--r--compiler/rustc_lint/src/types.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs9
-rw-r--r--compiler/rustc_passes/src/liveness.rs7
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs6
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs12
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs22
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs18
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs3
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs1
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs11
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs3
-rw-r--r--compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs8
-rw-r--r--src/librustdoc/scrape_examples.rs2
27 files changed, 115 insertions, 96 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 7df3520422c..8a45cd22953 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -68,10 +68,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParenthesizedGenericArgs::Err,
                         ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     ));
-                    let args = self.arena.alloc_from_iter(
-                        [&*receiver].into_iter().chain(args.iter()).map(|x| self.lower_expr_mut(x)),
-                    );
-                    hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span))
+                    let receiver = self.lower_expr(receiver);
+                    let args =
+                        self.arena.alloc_from_iter(args.iter().map(|x| self.lower_expr_mut(x)));
+                    hir::ExprKind::MethodCall(hir_seg, receiver, args, self.lower_span(span))
                 }
                 ExprKind::Binary(binop, ref lhs, ref rhs) => {
                     let binop = self.lower_binop(binop);
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index dd9590016b9..f168a44c043 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -711,8 +711,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                             Applicability::MachineApplicable,
                         );
                         self.suggested = true;
-                    } else if let hir::ExprKind::MethodCall(_path, args @ [_, ..], sp) = expr.kind
-                        && let hir::ExprKind::Index(val, index) = args[0].kind
+                    } else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
+                        && let hir::ExprKind::Index(val, index) = receiver.kind
                         && expr.span == self.assign_span
                     {
                         // val[index].path(args..);
@@ -724,7 +724,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                     ".get_mut(".to_string(),
                                 ),
                                 (
-                                    index.span.shrink_to_hi().with_hi(args[0].span.hi()),
+                                    index.span.shrink_to_hi().with_hi(receiver.span.hi()),
                                     ").map(|val| val".to_string(),
                                 ),
                                 (sp.shrink_to_hi(), ")".to_string()),
@@ -911,11 +911,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                                         [
                                                             Expr {
                                                                 kind:
-                                                                    MethodCall(
-                                                                        path_segment,
-                                                                        _args,
-                                                                        span,
-                                                                    ),
+                                                                    MethodCall(path_segment, _, _, span),
                                                                 hir_id,
                                                                 ..
                                                             },
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 082dd869023..31233062e9b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -901,13 +901,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         match expr.kind {
             hir::ExprKind::MethodCall(.., args, _) => {
                 // only the first closre parameter of the method. args[0] is MethodCall PathSegment
-                for i in 1..args.len() {
+
+                for arg in args {
                     if let hir::ExprKind::Closure(hir::Closure {
                         capture_clause: hir::CaptureBy::Ref,
                         ..
-                    }) = args[i].kind
-                    {
-                        closure_span = Some(args[i].span.shrink_to_lo());
+                    }) = arg.kind {
+                        closure_span = Some(arg.span.shrink_to_lo());
                         break;
                     }
                 }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 08282f13897..3367df56a29 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1893,7 +1893,7 @@ pub enum ExprKind<'hir> {
     /// the `hir_id` of the `MethodCall` node itself.
     ///
     /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id
-    MethodCall(&'hir PathSegment<'hir>, &'hir [Expr<'hir>], Span),
+    MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
     /// A tuple (e.g., `(a, b, c, d)`).
     Tup(&'hir [Expr<'hir>]),
     /// A binary operation (e.g., `a + b`, `a * b`).
@@ -3497,7 +3497,7 @@ mod size_asserts {
     // These are in alphabetical order, which is easy to maintain.
     static_assert_size!(Block<'_>, 48);
     static_assert_size!(Body<'_>, 32);
-    static_assert_size!(Expr<'_>, 56);
+    static_assert_size!(Expr<'_>, 64);
     static_assert_size!(ExprKind<'_>, 40);
     static_assert_size!(FnDecl<'_>, 40);
     static_assert_size!(ForeignItem<'_>, 72);
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 3d5e22add71..2f9b92bfb9f 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1094,8 +1094,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
             visitor.visit_expr(callee_expression);
             walk_list!(visitor, visit_expr, arguments);
         }
-        ExprKind::MethodCall(ref segment, arguments, _) => {
+        ExprKind::MethodCall(ref segment, receiver, arguments, _) => {
             visitor.visit_path_segment(expression.span, segment);
+            visitor.visit_expr(receiver);
             walk_list!(visitor, visit_expr, arguments);
         }
         ExprKind::Binary(_, ref left_expression, ref right_expression) => {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 42663da8a3f..bb694bacfd7 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1181,9 +1181,14 @@ impl<'a> State<'a> {
         self.print_call_post(args)
     }
 
-    fn print_expr_method_call(&mut self, segment: &hir::PathSegment<'_>, args: &[hir::Expr<'_>]) {
-        let base_args = &args[1..];
-        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
+    fn print_expr_method_call(
+        &mut self,
+        segment: &hir::PathSegment<'_>,
+        receiver: &hir::Expr<'_>,
+        args: &[hir::Expr<'_>],
+    ) {
+        let base_args = args;
+        self.print_expr_maybe_paren(&receiver, parser::PREC_POSTFIX);
         self.word(".");
         self.print_ident(segment.ident);
 
@@ -1394,8 +1399,8 @@ impl<'a> State<'a> {
             hir::ExprKind::Call(func, args) => {
                 self.print_expr_call(func, args);
             }
-            hir::ExprKind::MethodCall(segment, args, _) => {
-                self.print_expr_method_call(segment, args);
+            hir::ExprKind::MethodCall(segment, receiver, args, _) => {
+                self.print_expr_method_call(segment, receiver, args);
             }
             hir::ExprKind::Binary(op, lhs, rhs) => {
                 self.print_expr_binary(op, lhs, rhs);
@@ -2413,9 +2418,9 @@ fn contains_exterior_struct_lit(value: &hir::Expr<'_>) -> bool {
             contains_exterior_struct_lit(x)
         }
 
-        hir::ExprKind::MethodCall(.., exprs, _) => {
+        hir::ExprKind::MethodCall(_, receiver, ..) => {
             // `X { y: 1 }.bar(...)`
-            contains_exterior_struct_lit(&exprs[0])
+            contains_exterior_struct_lit(receiver)
         }
 
         _ => false,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 91a05367eee..9efd909f05b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -901,7 +901,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     }
                 }
             }
-            hir::ExprKind::MethodCall(segment, _, _) => {
+            hir::ExprKind::MethodCall(segment, ..) => {
                 if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
                     let generics = tcx.generics_of(def_id);
                     let insertable: Option<_> = try {
@@ -1132,7 +1132,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
                 let generic_args = &generics.own_substs_no_defaults(tcx, substs)
                     [generics.own_counts().lifetimes..];
                 let span = match expr.kind {
-                    ExprKind::MethodCall(path, _, _) => path.ident.span,
+                    ExprKind::MethodCall(path, ..) => path.ident.span,
                     _ => expr.span,
                 };
 
@@ -1181,7 +1181,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             })
             .any(|generics| generics.has_impl_trait())
         };
-        if let ExprKind::MethodCall(path, args, span) = expr.kind
+        if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind
             && let Some(substs) = self.node_substs_opt(expr.hir_id)
             && substs.iter().any(|arg| self.generic_arg_contains_target(arg))
             && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
@@ -1189,12 +1189,12 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             && !has_impl_trait(def_id)
         {
             let successor =
-                args.get(1).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
+                args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
             let substs = self.infcx.resolve_vars_if_possible(substs);
             self.update_infer_source(InferSource {
                 span: path.ident.span,
                 kind: InferSourceKind::FullyQualifiedMethodCall {
-                    receiver: args.first().unwrap(),
+                    receiver,
                     successor,
                     substs,
                     def_id,
diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs
index 121fefdc620..fb79daf29ee 100644
--- a/compiler/rustc_lint/src/array_into_iter.rs
+++ b/compiler/rustc_lint/src/array_into_iter.rs
@@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
         }
 
         // We only care about method call expressions.
-        if let hir::ExprKind::MethodCall(call, args, _) = &expr.kind {
+        if let hir::ExprKind::MethodCall(call, receiver, ..) = &expr.kind {
             if call.ident.name != sym::into_iter {
                 return;
             }
@@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
             };
 
             // As this is a method call expression, we have at least one argument.
-            let receiver_arg = &args[0];
+            let receiver_arg = receiver;
             let receiver_ty = cx.typeck_results().expr_ty(receiver_arg);
             let adjustments = cx.typeck_results().expr_adjustments(receiver_arg);
 
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 48942211eba..7d62d5ac98d 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2412,13 +2412,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
                         _ => {}
                     }
                 }
-            } else if let hir::ExprKind::MethodCall(_, ref args, _) = expr.kind {
+            } else if let hir::ExprKind::MethodCall(_, receiver, ..) = expr.kind {
                 // Find problematic calls to `MaybeUninit::assume_init`.
                 let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
                 if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) {
                     // This is a call to *some* method named `assume_init`.
                     // See if the `self` parameter is one of the dangerous constructors.
-                    if let hir::ExprKind::Call(ref path_expr, _) = args[0].kind {
+                    if let hir::ExprKind::Call(ref path_expr, _) = receiver.kind {
                         if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
                             let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
                             match cx.tcx.get_diagnostic_name(def_id) {
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 16b7d2cbbae..23e7f21adf8 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -51,7 +51,7 @@ fn typeck_results_of_method_fn<'tcx>(
     expr: &Expr<'_>,
 ) -> Option<(Span, DefId, ty::subst::SubstsRef<'tcx>)> {
     match expr.kind {
-        ExprKind::MethodCall(segment, _, _)
+        ExprKind::MethodCall(segment, ..)
             if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) =>
         {
             Some((segment.ident.span, def_id, cx.typeck_results().node_substs(expr.hir_id)))
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs
index ff5a01749c1..646812589e3 100644
--- a/compiler/rustc_lint/src/methods.rs
+++ b/compiler/rustc_lint/src/methods.rs
@@ -44,9 +44,13 @@ fn in_macro(span: Span) -> bool {
 
 fn first_method_call<'tcx>(
     expr: &'tcx Expr<'tcx>,
-) -> Option<(&'tcx PathSegment<'tcx>, &'tcx [Expr<'tcx>])> {
-    if let ExprKind::MethodCall(path, args, _) = &expr.kind {
-        if args.iter().any(|e| e.span.from_expansion()) { None } else { Some((path, *args)) }
+) -> Option<(&'tcx PathSegment<'tcx>, &'tcx Expr<'tcx>)> {
+    if let ExprKind::MethodCall(path, receiver, args, ..) = &expr.kind {
+        if args.iter().any(|e| e.span.from_expansion()) || receiver.span.from_expansion() {
+            None
+        } else {
+            Some((path, *receiver))
+        }
     } else {
         None
     }
@@ -59,14 +63,14 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr {
         }
 
         match first_method_call(expr) {
-            Some((path, args)) if path.ident.name == sym::as_ptr => {
-                let unwrap_arg = &args[0];
+            Some((path, receiver)) if path.ident.name == sym::as_ptr => {
+                let unwrap_arg = receiver;
                 let as_ptr_span = path.ident.span;
                 match first_method_call(unwrap_arg) {
-                    Some((path, args))
+                    Some((path, receiver))
                         if path.ident.name == sym::unwrap || path.ident.name == sym::expect =>
                     {
-                        let source_arg = &args[0];
+                        let source_arg = receiver;
                         lint_cstring_as_ptr(cx, as_ptr_span, source_arg, unwrap_arg);
                     }
                     _ => return,
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index 11a752ff097..d1449496d33 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -41,7 +41,7 @@ declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]);
 impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         // We only care about method calls.
-        let ExprKind::MethodCall(call, elements, _) = &expr.kind else {
+        let ExprKind::MethodCall(call, receiver, ..) = &expr.kind else {
             return
         };
         // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
@@ -81,7 +81,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
         ) {
             return;
         }
-        let receiver = &elements[0];
         let receiver_ty = cx.typeck_results().expr_ty(receiver);
         let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
         if receiver_ty != expr_ty {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 03166519981..9736b555703 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1458,7 +1458,7 @@ impl InvalidAtomicOrdering {
             sym::AtomicI64,
             sym::AtomicI128,
         ];
-        if let ExprKind::MethodCall(ref method_path, args, _) = &expr.kind
+        if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind
             && recognized_names.contains(&method_path.ident.name)
             && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
             && let Some(impl_did) = cx.tcx.impl_of_method(m_def_id)
@@ -1494,8 +1494,8 @@ impl InvalidAtomicOrdering {
     fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) {
         if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store])
             && let Some((ordering_arg, invalid_ordering)) = match method {
-                sym::load => Some((&args[1], sym::Release)),
-                sym::store => Some((&args[2], sym::Acquire)),
+                sym::load => Some((&args[0], sym::Release)),
+                sym::store => Some((&args[1], sym::Acquire)),
                 _ => None,
             }
             && let Some(ordering) = Self::match_ordering(cx, ordering_arg)
@@ -1536,8 +1536,8 @@ impl InvalidAtomicOrdering {
             else {return };
 
         let fail_order_arg = match method {
-            sym::fetch_update => &args[2],
-            sym::compare_exchange | sym::compare_exchange_weak => &args[4],
+            sym::fetch_update => &args[1],
+            sym::compare_exchange | sym::compare_exchange_weak => &args[3],
             _ => return,
         };
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 9ed1c064d2b..b4b5a9d868d 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -261,15 +261,18 @@ impl<'tcx> Cx<'tcx> {
 
         let kind = match expr.kind {
             // Here comes the interesting stuff:
-            hir::ExprKind::MethodCall(segment, ref args, fn_span) => {
+            hir::ExprKind::MethodCall(segment, receiver, ref args, fn_span) => {
                 // Rewrite a.b(c) into UFCS form like Trait::b(a, c)
                 let expr = self.method_callee(expr, segment.ident.span, None);
                 // When we apply adjustments to the receiver, use the span of
                 // the overall method call for better diagnostics. args[0]
                 // is guaranteed to exist, since a method call always has a receiver.
-                let old_adjustment_span = self.adjustment_span.replace((args[0].hir_id, expr_span));
+                let old_adjustment_span = self.adjustment_span.replace((receiver.hir_id, expr_span));
                 info!("Using method span: {:?}", expr.span);
-                let args = self.mirror_exprs(args);
+                let args = std::iter::once(receiver)
+                    .chain(args.iter())
+                    .map(|expr| self.mirror_expr(expr))
+                    .collect();
                 self.adjustment_span = old_adjustment_span;
                 ExprKind::Call {
                     ty: expr.ty,
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 2a6889af7c2..214d357cae0 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1039,9 +1039,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 self.propagate_through_expr(&f, succ)
             }
 
-            hir::ExprKind::MethodCall(.., ref args, _) => {
+            hir::ExprKind::MethodCall(.., receiver, ref args, _) => {
                 let succ = self.check_is_ty_uninhabited(expr, succ);
-                self.propagate_through_exprs(args, succ)
+                std::iter::once(receiver)
+                    .chain(args.iter())
+                    .rev()
+                    .fold(succ, |succ, expr| self.propagate_through_expr(expr, succ))
             }
 
             hir::ExprKind::Tup(ref exprs) => self.propagate_through_exprs(exprs, succ),
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index c9fc6b9e47a..1bd6b857e06 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -803,6 +803,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         &mut self,
         ex: &'tcx hir::Expr<'tcx>,
         seg: &'tcx hir::PathSegment<'tcx>,
+        receiver: &'tcx hir::Expr<'tcx>,
         args: &'tcx [hir::Expr<'tcx>],
     ) {
         debug!("process_method_call {:?} {:?}", ex, ex.span);
@@ -823,6 +824,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         }
 
         // walk receiver and args
+        self.visit_expr(receiver);
         walk_list!(self, visit_expr, args);
     }
 
@@ -1340,7 +1342,9 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 let res = self.save_ctxt.get_path_res(hir_expr.hir_id);
                 self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), *rest)
             }
-            hir::ExprKind::MethodCall(ref seg, args, _) => self.process_method_call(ex, seg, args),
+            hir::ExprKind::MethodCall(ref seg, receiver, args, _) => {
+                self.process_method_call(ex, seg, receiver, args)
+            }
             hir::ExprKind::Field(ref sub_ex, _) => {
                 self.visit_expr(&sub_ex);
 
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 4a3d69f5b6c..7ea3ed06e61 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -590,7 +590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let closure_params_len = closure_fn_decl.inputs.len();
         let (
             Some(Node::Expr(hir::Expr {
-                kind: hir::ExprKind::MethodCall(method_path, method_expr, _),
+                kind: hir::ExprKind::MethodCall(method_path, receiver, ..),
                 ..
             })),
             1,
@@ -598,7 +598,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        let self_ty = self.typeck_results.borrow().expr_ty(&method_expr[0]);
+        let self_ty = self.typeck_results.borrow().expr_ty(receiver);
         let name = method_path.ident.name;
         let is_as_ref_able = match self_ty.peel_refs().kind() {
             ty::Adt(def, _) => {
@@ -767,11 +767,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
                 if self.can_coerce(ref_ty, expected) {
                     let mut sugg_sp = sp;
-                    if let hir::ExprKind::MethodCall(ref segment, ref args, _) = expr.kind {
+                    if let hir::ExprKind::MethodCall(ref segment, receiver, args, _) = expr.kind {
                         let clone_trait =
                             self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span));
-                        if let ([arg], Some(true), sym::clone) = (
-                            &args[..],
+                        if let (true, Some(true), sym::clone) = (
+                            args.is_empty(),
                             self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
                                 |did| {
                                     let ai = self.tcx.associated_item(did);
@@ -782,7 +782,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ) {
                             // If this expression had a clone call when suggesting borrowing
                             // we want to suggest removing it because it'd now be unnecessary.
-                            sugg_sp = arg.span;
+                            sugg_sp = receiver.span;
                         }
                     }
                     if let Ok(src) = sm.span_to_snippet(sugg_sp) {
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 17ec8afc737..5c7b8121a61 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -324,8 +324,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ExprKind::Block(body, _) => self.check_block_with_expected(&body, expected),
             ExprKind::Call(callee, args) => self.check_call(expr, &callee, args, expected),
-            ExprKind::MethodCall(segment, args, _) => {
-                self.check_method_call(expr, segment, args, expected)
+            ExprKind::MethodCall(segment, receiver, args, _) => {
+                self.check_method_call(expr, segment, receiver, args, expected)
             }
             ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
             ExprKind::Type(e, t) => {
@@ -1195,13 +1195,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         segment: &hir::PathSegment<'_>,
+        receiver: &'tcx hir::Expr<'tcx>,
         args: &'tcx [hir::Expr<'tcx>],
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        let rcvr = &args[0];
+        let rcvr = &receiver;
         let rcvr_t = self.check_expr(&rcvr);
         // no need to check for bot/err -- callee does that
-        let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
+        let rcvr_t = self.structurally_resolved_type(receiver.span, rcvr_t);
         let span = segment.ident.span;
 
         let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {
@@ -1218,9 +1219,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span,
                         rcvr_t,
                         segment.ident,
-                        SelfSource::MethodCall(&args[0]),
+                        SelfSource::MethodCall(receiver),
                         error,
-                        Some(args),
+                        Some((receiver, args)),
                     ) {
                         err.emit();
                     }
@@ -1230,14 +1231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Call the generic checker.
-        self.check_method_argument_types(
-            span,
-            expr,
-            method,
-            &args[1..],
-            DontTupleArguments,
-            expected,
-        )
+        self.check_method_argument_types(span, expr, method, &args, DontTupleArguments, expected)
     }
 
     fn check_expr_cast(
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 7e746b7387a..c59638f5d6f 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -987,7 +987,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if found != self.tcx.types.unit {
             return;
         }
-        if let ExprKind::MethodCall(path_segment, [rcvr, ..], _) = expr.kind {
+        if let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind {
             if self
                 .typeck_results
                 .borrow()
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index d1d27db9131..3805de3cd4d 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -478,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None, false),
-            hir::ExprKind::MethodCall(path_segment, _, span) => {
+            hir::ExprKind::MethodCall(path_segment, _, _, span) => {
                 let ident_span = path_segment.ident.span;
                 let ident_span = if let Some(args) = path_segment.args {
                     ident_span.with_hi(args.span_ext.hi())
@@ -530,13 +530,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .collect();
         let callee_expr = match &call_expr.peel_blocks().kind {
             hir::ExprKind::Call(callee, _) => Some(*callee),
-            hir::ExprKind::MethodCall(_, callee, _) => {
+            hir::ExprKind::MethodCall(_, receiver, ..) => {
                 if let Some((DefKind::AssocFn, def_id)) =
                     self.typeck_results.borrow().type_dependent_def(call_expr.hir_id)
                     && let Some(assoc) = tcx.opt_associated_item(def_id)
                     && assoc.fn_has_self_parameter
                 {
-                    Some(&callee[0])
+                    Some(*receiver)
                 } else {
                     None
                 }
@@ -1805,6 +1805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 param,
                                 *call_hir_id,
                                 callee.span,
+                                None,
                                 args,
                             )
                         {
@@ -1823,7 +1824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 }
             }
-            hir::ExprKind::MethodCall(segment, args, ..) => {
+            hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
                 for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
                     .into_iter()
                     .flatten()
@@ -1834,6 +1835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         param,
                         hir_id,
                         segment.ident.span,
+                        Some(receiver),
                         args,
                     ) {
                         return true;
@@ -1901,7 +1903,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         param_to_point_at: ty::GenericArg<'tcx>,
         call_hir_id: hir::HirId,
         callee_span: Span,
-        args: &[hir::Expr<'tcx>],
+        receiver: Option<&'tcx hir::Expr<'tcx>>,
+        args: &'tcx [hir::Expr<'tcx>],
     ) -> bool {
         let sig = self.tcx.fn_sig(def_id).skip_binder();
         let args_referencing_param: Vec<_> = sig
@@ -1910,6 +1913,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .enumerate()
             .filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at))
             .collect();
+        let args: Vec<&'tcx hir::Expr<'tcx>> = if let Some(receiver) = receiver {
+            std::iter::once(receiver).chain(args.iter()).collect()
+        } else {
+            args.iter().collect()
+        };
 
         // If there's one field that references the given generic, great!
         if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index d8527b9267e..3d9677ecf75 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -1049,7 +1049,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         found_ty: Ty<'tcx>,
         expr: &hir::Expr<'_>,
     ) {
-        let hir::ExprKind::MethodCall(segment, &[ref callee_expr], _) = expr.kind else { return; };
+        let hir::ExprKind::MethodCall(segment, callee_expr, &[], _) = expr.kind else { return; };
         let Some(clone_trait_did) = self.tcx.lang_items().clone_trait() else { return; };
         let ty::Ref(_, pointee_ty, _) = found_ty.kind() else { return };
         let results = self.typeck_results.borrow();
diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
index 3e96b3ffb09..016f4056bd9 100644
--- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs
@@ -434,7 +434,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
 
                 self.handle_uninhabited_return(expr);
             }
-            ExprKind::MethodCall(_, exprs, _) => {
+            ExprKind::MethodCall(_, receiver, exprs, _) => {
+                self.visit_expr(receiver);
                 for expr in exprs {
                     self.visit_expr(expr);
                 }
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index 7c68d930405..392695cca68 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -160,7 +160,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if precise {
                         let args = args
                             .iter()
-                            .skip(1)
                             .map(|arg| {
                                 let span = arg.span.find_ancestor_inside(sp).unwrap_or_default();
                                 format!(
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 998405bcbe1..124ac5c24fa 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -95,7 +95,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         item_name: Ident,
         source: SelfSource<'tcx>,
         error: MethodError<'tcx>,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
+        args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
     ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
         // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
@@ -998,7 +998,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         span,
                         rcvr_ty,
                         item_name,
-                        args.map(|args| args.len()),
+                        args.map(|(_, args)| args.len() + 1),
                         source,
                         out_of_scope_traits,
                         &unsatisfied_predicates,
@@ -2310,7 +2310,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
 
 fn print_disambiguation_help<'tcx>(
     item_name: Ident,
-    args: Option<&'tcx [hir::Expr<'tcx>]>,
+    args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
     err: &mut Diagnostic,
     trait_name: String,
     rcvr_ty: Ty<'_>,
@@ -2322,7 +2322,7 @@ fn print_disambiguation_help<'tcx>(
     fn_has_self_parameter: bool,
 ) {
     let mut applicability = Applicability::MachineApplicable;
-    let (span, sugg) = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) {
+    let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
         let args = format!(
             "({}{})",
             if rcvr_ty.is_region_ptr() {
@@ -2330,7 +2330,8 @@ fn print_disambiguation_help<'tcx>(
             } else {
                 ""
             },
-            args.iter()
+            std::iter::once(receiver)
+                .chain(args.iter())
                 .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {
                     applicability = Applicability::HasPlaceholders;
                     "_".to_owned()
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index bfc4f061b70..f483342b445 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -233,8 +233,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 self.consume_exprs(args);
             }
 
-            hir::ExprKind::MethodCall(.., args, _) => {
+            hir::ExprKind::MethodCall(.., receiver, args, _) => {
                 // callee.m(args)
+                self.consume_expr(receiver);
                 self.consume_exprs(args);
             }
 
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index d4b5e5e2fe4..ec5d03300b1 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -758,13 +758,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         num_assoc_fn_excess_args: usize,
         num_trait_generics_except_self: usize,
     ) {
-        if let hir::ExprKind::MethodCall(_, args, _) = expr.kind {
-            assert_eq!(args.len(), 1);
+        if let hir::ExprKind::MethodCall(_, receiver, args, ..) = expr.kind {
+            assert_eq!(args.len(), 0);
             if num_assoc_fn_excess_args == num_trait_generics_except_self {
                 if let Some(gen_args) = self.gen_args.span_ext()
                 && let Ok(gen_args) = self.tcx.sess.source_map().span_to_snippet(gen_args)
-                && let Ok(args) = self.tcx.sess.source_map().span_to_snippet(args[0].span) {
-                    let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), args);
+                && let Ok(receiver) = self.tcx.sess.source_map().span_to_snippet(receiver.span) {
+                    let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), receiver);
                     err.span_suggestion(expr.span, msg, sugg, Applicability::MaybeIncorrect);
                 }
             }
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 0d968402503..ca86ac89e85 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -159,7 +159,7 @@ where
                     return;
                 }
             }
-            hir::ExprKind::MethodCall(path, _, call_span) => {
+            hir::ExprKind::MethodCall(path, _, _, call_span) => {
                 let types = tcx.typeck(ex.hir_id.owner);
                 let Some(def_id) = types.type_dependent_def_id(ex.hir_id) else {
                     trace!("type_dependent_def_id({}) = None", ex.hir_id);