about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap48
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs157
-rw-r--r--src/doc/style-guide/src/editions.md4
-rw-r--r--src/doc/style-guide/src/expressions.md25
-rw-r--r--src/doc/style-guide/src/items.md30
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs3
-rw-r--r--tests/rustdoc-gui/item-info.goml23
-rw-r--r--tests/rustdoc/type-alias/deeply-nested-112515.rs2
-rw-r--r--tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs2
-rw-r--r--tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs2
-rw-r--r--tests/ui/indexing/indexing-spans-caller-location.rs2
-rw-r--r--tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs2
-rw-r--r--tests/ui/issues/issue-12567.stderr28
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr7
-rw-r--r--tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.fixed10
-rw-r--r--tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.rs10
-rw-r--r--tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.stderr18
-rw-r--r--tests/ui/nll/move-errors.stderr7
-rw-r--r--tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr10
-rw-r--r--tests/ui/suggestions/dont-suggest-ref/simple.rs22
-rw-r--r--tests/ui/suggestions/dont-suggest-ref/simple.stderr77
-rw-r--r--tests/ui/suggestions/option-content-move-from-tuple-match.stderr7
22 files changed, 331 insertions, 165 deletions
diff --git a/.mailmap b/.mailmap
index 874a42656c5..18a9e5e44ec 100644
--- a/.mailmap
+++ b/.mailmap
@@ -48,6 +48,7 @@ Andrew Poelstra <asp11@sfu.ca> <apoelstra@wpsoftware.net>
 Anhad Singh <andypythonappdeveloper@gmail.com>
 Antoine Plaskowski <antoine.plaskowski@epitech.eu>
 Anton Löfgren <anton.lofgren@gmail.com> <alofgren@op5.com>
+apiraino <apiraino@users.noreply.github.com> <apiraino@protonmail.com>
 Araam Borhanian <avborhanian@gmail.com>
 Araam Borhanian <avborhanian@gmail.com> <dobbybabee@gmail.com>
 Areski Belaid <areski@gmail.com> areski <areski@gmail.com>
@@ -62,7 +63,10 @@ Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org>
 Ayaz Hafiz <ayaz.hafiz.1@gmail.com>
 Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com>
 Ayush Mishra <ayushmishra2005@gmail.com>
+Ashley Mannix <kodraus@hey.com> <ashleymannix@live.com.au>
 asrar <aszenz@gmail.com>
+b-naber <bn263@gmx.de>
+b-naber <bn263@gmx.de> <b_naber@gmx.de>
 BaoshanPang <pangbw@gmail.com>
 Barosl Lee <vcs@barosl.com> Barosl LEE <github@barosl.com>
 Bastian Kersting <bastian@cmbt.de>
@@ -98,6 +102,8 @@ Caleb Cartwright <caleb.cartwright@outlook.com>
 Caleb Jones <code@calebjones.net>
 Noah Lev <camelidcamel@gmail.com>
 Noah Lev <camelidcamel@gmail.com> <37223377+camelid@users.noreply.github.com>
+Catherine <catherine3.flores@gmail.com>
+Catherine <catherine3.flores@gmail.com> <catherine.3.flores@gmail.com>
 cameron1024 <cameron.studdstreet@gmail.com>
 Camille Gillot <gillot.camille@gmail.com>
 Carl-Anton Ingmarsson <mail@carlanton.se> <ca.ingmarsson@gmail.com>
@@ -133,11 +139,13 @@ Clement Miao <clementmiao@gmail.com>
 Clément Renault <renault.cle@gmail.com>
 Cliff Dyer <jcd@sdf.org>
 Clinton Ryan <clint.ryan3@gmail.com>
+Taylor Cramer <cramertaylorj@gmail.com> <cramertj@google.com>
 ember arlynx <ember@lunar.town> <corey@octayn.net>
 Crazycolorz5 <Crazycolorz5@gmail.com>
 csmoe <35686186+csmoe@users.noreply.github.com>
 Cyryl Płotnicki <cyplo@cyplo.net>
 Damien Schoof <damien.schoof@gmail.com>
+Dan Gohman <dev@sunfishcode.online> <sunfish@mozilla.com>
 Dan Robertson <danlrobertson89@gmail.com>
 Daniel Campoverde <alx741@riseup.net>
 Daniel J Rollins <drollins@financialforce.com>
@@ -179,10 +187,14 @@ Eduardo Bautista <me@eduardobautista.com> <=>
 Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com>
 Eduardo Broto <ebroto@tutanota.com>
 Edward Shen <code@eddie.sh> <xes@meta.com>
+Jacob Finkelman <eh2406@wayne.edu>
+Jacob Finkelman <eh2406@wayne.edu> <YeomanYaacov@gmail.com>
 Elliott Slaughter <elliottslaughter@gmail.com> <eslaughter@mozilla.com>
 Elly Fong-Jones <elly@leptoquark.net>
 Eric Holk <eric.holk@gmail.com> <eholk@cs.indiana.edu>
 Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com>
+Eric Holk <eric.holk@gmail.com> <eric@theincredibleholk.org>
+Eric Holk <eric.holk@gmail.com> <ericholk@microsoft.com>
 Eric Holmes <eric@ejholmes.net>
 Eric Reed <ecreed@cs.washington.edu> <ereed@mozilla.com>
 Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org>
@@ -206,6 +218,7 @@ Felix S. Klock II <pnkfelix@pnkfx.org> <pnkfelix@mozilla.com>
 Félix Saparelli <felix@passcod.name>
 Flaper Fesp <flaper87@gmail.com>
 Florian Berger <fbergr@gmail.com>
+Florian Gilcher <florian.gilcher@asquera.de> <flo@andersground.net>
 Florian Wilkens <mrfloya_github@outlook.com> Florian Wilkens <floya@live.de>
 François Mockers <mockersf@gmail.com>
 Frank Steffahn <fdsteffahn@gmail.com> <frank.steffahn@stu.uni-kiel.de>
@@ -240,6 +253,8 @@ Herman J. Radtke III <herman@hermanradtke.com> Herman J. Radtke III <hermanradtk
 Hirochika Matsumoto <git@hkmatsumoto.com> <matsujika@gmail.com>
 Hrvoje Nikšić <hniksic@gmail.com>
 Hsiang-Cheng Yang <rick68@users.noreply.github.com>
+Huon Wilson <dbau.pp@gmail.com>
+Huon Wilson <dbau.pp@gmail.com> <wilson.huon@gmail.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org>
@@ -252,9 +267,13 @@ ivan tkachenko <me@ratijas.tk>
 J. J. Weber <jjweber@gmail.com>
 Jack Huey <jack.huey@umassmed.edu> <jackh726@gmail.com>
 Jacob <jacob.macritchie@gmail.com>
+Jacob Hoffman-Andrews <rust@hoffman-andrews.com> <github@hoffman-andrews.com>
 Jacob Greenfield <xales@naveria.com>
 Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com>
 Jacob Pratt <jacob@jhpratt.dev> <jacopratt@tesla.com>
+Jake Goulding <jake.goulding@integer32.com>
+Jake Goulding <jake.goulding@integer32.com> <jake.goulding@gmail.com> 
+Jake Goulding <jake.goulding@integer32.com> <shepmaster@mac.com>
 Jake Vossen <jake@vossen.dev>
 Jakob Degen <jakob.e.degen@gmail.com> <jakob@degen.com>
 Jakob Lautrup Nysom <jako3047@gmail.com>
@@ -287,6 +306,7 @@ Jerry Hardee <hardeejj9@gmail.com>
 Jesús Rubio <jesusprubio@gmail.com>
 Jethro Beekman <github@jbeekman.nl>
 Jian Zeng <knight42@mail.ustc.edu.cn>
+Jieyou Xu <jieyouxu@outlook.com>
 Jieyou Xu <jieyouxu@outlook.com> <39484203+jieyouxu@users.noreply.github.com>
 Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
 Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>
@@ -322,9 +342,12 @@ Josh Holmer <jholmer.in@gmail.com>
 Josh Stone <cuviper@gmail.com> <jistone@redhat.com>
 Josh Stone <cuviper@gmail.com> <jistone@fedoraproject.org>
 Julia Ryan <juliaryan3.14@gmail.com> <josephryan3.14@gmail.com>
+Jubilee Young <workingjubilee@gmail.com> <46493976+workingjubilee@users.noreply.github.com>
+Jubilee Young <workingjubilee@gmail.com>
 Julian Knodt <julianknodt@gmail.com>
 jumbatm <jumbatm@gmail.com> <30644300+jumbatm@users.noreply.github.com>
 Junyoung Cho <june0.cho@samsung.com>
+Jynn Nelson <github@jyn.dev> <rust@jyn.dev>
 Jynn Nelson <github@jyn.dev> <jyn514@gmail.com>
 Jynn Nelson <github@jyn.dev> <joshua@yottadb.com>
 Jynn Nelson <github@jyn.dev> <jyn.nelson@redjack.com>
@@ -385,12 +408,14 @@ Marcell Pardavi <marcell.pardavi@gmail.com>
 Marcus Klaas de Vries <mail@marcusklaas.nl>
 Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
 Mark Mansi <markm@cs.wisc.edu>
+Mark Mansi <markm@cs.wisc.edu> <m.mim95@gmail.com>
 Mark Rousskov <mark.simulacrum@gmail.com>
 Mark Sinclair <mark.edward.x@gmail.com>
 Mark Sinclair <mark.edward.x@gmail.com> =Mark Sinclair <=125axel125@gmail.com>
 Markus Legner <markus@legner.ch>
 Markus Westerlind <marwes91@gmail.com> Markus <marwes91@gmail.com>
 Martin Carton <cartonmartin+git@gmail.com>
+Martin Carton <cartonmartin+git@gmail.com> <cartonmartin@gmail.com>
 Martin Habovštiak <martin.habovstiak@gmail.com>
 Martin Hafskjold Thoresen <martinhath@gmail.com>
 Martin Nordholts <martin.nordholts@codetale.se> <enselic@gmail.com>
@@ -415,6 +440,7 @@ Melody Horn <melody@boringcactus.com> <mathphreak@gmail.com>
 Mendes <pedro.mendes.26@gmail.com>
 mental <m3nta1@yahoo.com>
 mibac138 <5672750+mibac138@users.noreply.github.com>
+Michael Howell <michael@notriddle.com> <notriddle+rust-mod@protonmail.com>
 Michael Williams <m.t.williams@live.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail.com>
@@ -431,6 +457,7 @@ Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
 msizanoen1 <qtmlabs@protonmail.com>
 Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
 Nadrieril Feneanar <Nadrieril@users.noreply.github.com>
+Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+rust@gmail.com>
 Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+git@gmail.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm+github@gmail.com>
@@ -447,15 +474,23 @@ Nicholas Bishop <nbishop@nbishop.net> <nicholasbishop@gmail.com>
 Nicholas Bishop <nbishop@nbishop.net> <nicholasbishop@google.com>
 Nicholas Nethercote <n.nethercote@gmail.com> <nnethercote@apple.com>
 Nicholas Nethercote <n.nethercote@gmail.com> <nnethercote@mozilla.com>
+Nick Cameron <nrc@ncameron.org> <ncameron@mozilla.com>
+Nick Fitzgerald <fitzgen@gmail.com> <nfitzgerald@mozilla.com>
 Nick Platt <platt.nicholas@gmail.com>
 Niclas Schwarzlose <15schnic@gmail.com>
 Nicolas Abram <abramlujan@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
+Niko Matsakis <rust@nikomatsakis.com>
+Niko Matsakis <rust@nikomatsakis.com> <niko@alum.mit.edu>
+Noratrieb <48135649+Noratrieb@users.noreply.github.com>
 Noratrieb <48135649+Noratrieb@users.noreply.github.com> <48135649+Nilstrieb@users.noreply.github.com>
 Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nilstrieb@gmail.com>
+Noratrieb <48135649+Noratrieb@users.noreply.github.com> <rust@noratrieb.dev>
 Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nora@noratrieb.dev>
 Nif Ward <nif.ward@gmail.com>
 Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com>
+Nikita Popov <nikita.ppv@gmail.com>
+Nikita Popov <nikita.ppv@gmail.com> <npopov@redhat.com>
 NODA Kai <nodakai@gmail.com>
 Oğuz Ağcayazı <oguz.agcayazi@gmail.com> <oguz.agcayazi@gmail.com>
 Oğuz Ağcayazı <oguz.agcayazi@gmail.com> <ouz.agz@gmail.com>
@@ -516,6 +551,7 @@ Ricky Hosfelt <ricky@hosfelt.io>
 Ritiek Malhotra <ritiekmalhotra123@gmail.com>
 Rob Arnold <robarnold@cs.cmu.edu>
 Rob Arnold <robarnold@cs.cmu.edu> Rob Arnold <robarnold@68-26-94-7.pools.spcsdns.net>
+Robert Collins <robertc@robertcollins.net> <robertc+rust@robertcollins.net>
 Robert Foss <dev@robertfoss.se> robertfoss <dev@robertfoss.se>
 Robert Gawdzik <rgawdzik@hotmail.com> Robert Gawdzik ☢ <rgawdzik@hotmail.com>
 Robert Habermeier <rphmeier@gmail.com>
@@ -553,7 +589,15 @@ Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
 Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me>
 Simonas Kazlauskas <git@kazlauskas.me> <simonas+t-compiler@kazlauskas.me>
 Siva Prasad <sivaauturic@gmail.com>
+Skgland <3877590+Skgland@users.noreply.github.com>
+Skgland <3877590+Skgland@users.noreply.github.com> <bb-github@t-online.de>
+Skgland <3877590+Skgland@users.noreply.github.com> <bennet.blessmann+github@googlemail.com>
 Smittyvb <me@smitop.com>
+Sophia June Turner <547158+sophiajt@users.noreply.github.com>
+Sophia June Turner <547158+sophiajt@users.noreply.github.com> <547158+jntrnr@users.noreply.github.com>
+Sophia June Turner <547158+sophiajt@users.noreply.github.com> <jonathandturner@users.noreply.github.com>
+Sophia June Turner <547158+sophiajt@users.noreply.github.com> <jturner@mozilla.com>
+Sophia June Turner <547158+sophiajt@users.noreply.github.com> <jonathan.d.turner@gmail.com>
 Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
 Stanislav Tkach <stanislav.tkach@gmail.com>
 startling <tdixon51793@gmail.com>
@@ -586,8 +630,10 @@ Tim Diekmann <t.diekmann.3dv@gmail.com>
 Tim Hutt <tdhutt@gmail.com>
 Tim JIANG <p90eri@gmail.com>
 Tim Joseph Dumol <tim@timdumol.com>
+Tim Neumann <mail@timnn.me> <timnn@google.com>
 Timothy Maloney <tmaloney@pdx.edu>
 Tomas Koutsky <tomas@stepnivlk.net>
+Tomasz Miąsko <tomasz.miasko@gmail.com>
 Torsten Weber <TorstenWeber12@gmail.com>
 Torsten Weber <TorstenWeber12@gmail.com> <torstenweber12@gmail.com>
 Trevor Gross <tmgross@umich.edu> <t.gross35@gmail.com>
@@ -607,7 +653,7 @@ Valerii Lashmanov <vflashm@gmail.com>
 Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
 Vitaly Shukela <vi0oss@gmail.com>
 Waffle Lapkin <waffle.lapkin@gmail.com>
-Waffle Lapkin <waffle.lapkin@tasking.com>
+Waffle Lapkin <waffle.lapkin@gmail.com> <waffle.lapkin@tasking.com>
 Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com>
 whitequark <whitequark@whitequark.org>
 William Ting <io@williamting.com> <william.h.ting@gmail.com>
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 4ba6b2e94ec..beacbdbd3fa 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -1,9 +1,10 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::{CaptureBy, ExprKind, HirId, Node};
+use rustc_hir::{self as hir, CaptureBy, ExprKind, HirId, Node};
 use rustc_middle::bug;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty};
@@ -683,48 +684,126 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     }
 
     fn add_move_error_suggestions(&self, err: &mut Diag<'_>, binds_to: &[Local]) {
-        let mut suggestions: Vec<(Span, String, String)> = Vec::new();
+        /// A HIR visitor to associate each binding with a `&` or `&mut` that could be removed to
+        /// make it bind by reference instead (if possible)
+        struct BindingFinder<'tcx> {
+            typeck_results: &'tcx ty::TypeckResults<'tcx>,
+            hir: rustc_middle::hir::map::Map<'tcx>,
+            /// Input: the span of the pattern we're finding bindings in
+            pat_span: Span,
+            /// Input: the spans of the bindings we're providing suggestions for
+            binding_spans: Vec<Span>,
+            /// Internal state: have we reached the pattern we're finding bindings in?
+            found_pat: bool,
+            /// Internal state: the innermost `&` or `&mut` "above" the visitor
+            ref_pat: Option<&'tcx hir::Pat<'tcx>>,
+            /// Internal state: could removing a `&` give bindings unexpected types?
+            has_adjustments: bool,
+            /// Output: for each input binding, the `&` or `&mut` to remove to make it by-ref
+            ref_pat_for_binding: Vec<(Span, Option<&'tcx hir::Pat<'tcx>>)>,
+            /// Output: ref patterns that can't be removed straightforwardly
+            cannot_remove: FxHashSet<HirId>,
+        }
+        impl<'tcx> Visitor<'tcx> for BindingFinder<'tcx> {
+            type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
+
+            fn nested_visit_map(&mut self) -> Self::Map {
+                self.hir
+            }
+
+            fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
+                // Don't walk into const patterns or anything else that might confuse this
+                if !self.found_pat {
+                    hir::intravisit::walk_expr(self, ex)
+                }
+            }
+
+            fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
+                if p.span == self.pat_span {
+                    self.found_pat = true;
+                }
+
+                let parent_has_adjustments = self.has_adjustments;
+                self.has_adjustments |=
+                    self.typeck_results.pat_adjustments().contains_key(p.hir_id);
+
+                // Track the innermost `&` or `&mut` enclosing bindings, to suggest removing it.
+                let parent_ref_pat = self.ref_pat;
+                if let hir::PatKind::Ref(..) = p.kind {
+                    self.ref_pat = Some(p);
+                    // To avoid edition-dependent logic to figure out how many refs this `&` can
+                    // peel off, simply don't remove the "parent" `&`.
+                    self.cannot_remove.extend(parent_ref_pat.map(|r| r.hir_id));
+                    if self.has_adjustments {
+                        // Removing this `&` could give child bindings unexpected types, so don't.
+                        self.cannot_remove.insert(p.hir_id);
+                        // As long the `&` stays, child patterns' types should be as expected.
+                        self.has_adjustments = false;
+                    }
+                }
+
+                if let hir::PatKind::Binding(_, _, ident, _) = p.kind {
+                    // the spans in `binding_spans` encompass both the ident and binding mode
+                    if let Some(&bind_sp) =
+                        self.binding_spans.iter().find(|bind_sp| bind_sp.contains(ident.span))
+                    {
+                        self.ref_pat_for_binding.push((bind_sp, self.ref_pat));
+                    } else {
+                        // we've encountered a binding that we're not reporting a move error for.
+                        // we don't want to change its type, so don't remove the surrounding `&`.
+                        if let Some(ref_pat) = self.ref_pat {
+                            self.cannot_remove.insert(ref_pat.hir_id);
+                        }
+                    }
+                }
+
+                hir::intravisit::walk_pat(self, p);
+                self.ref_pat = parent_ref_pat;
+                self.has_adjustments = parent_has_adjustments;
+            }
+        }
+        let mut pat_span = None;
+        let mut binding_spans = Vec::new();
         for local in binds_to {
             let bind_to = &self.body.local_decls[*local];
-            if let LocalInfo::User(BindingForm::Var(VarBindingForm { pat_span, .. })) =
+            if let LocalInfo::User(BindingForm::Var(VarBindingForm { pat_span: pat_sp, .. })) =
                 *bind_to.local_info()
             {
-                let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
-                else {
-                    continue;
-                };
-                let Some(stripped) = pat_snippet.strip_prefix('&') else {
-                    suggestions.push((
-                        bind_to.source_info.span.shrink_to_lo(),
-                        "consider borrowing the pattern binding".to_string(),
-                        "ref ".to_string(),
-                    ));
-                    continue;
-                };
-                let inner_pat_snippet = stripped.trim_start();
-                let (pat_span, suggestion, to_remove) = if inner_pat_snippet.starts_with("mut")
-                    && inner_pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
-                {
-                    let inner_pat_snippet = inner_pat_snippet["mut".len()..].trim_start();
-                    let pat_span = pat_span.with_hi(
-                        pat_span.lo()
-                            + BytePos((pat_snippet.len() - inner_pat_snippet.len()) as u32),
-                    );
-                    (pat_span, String::new(), "mutable borrow")
-                } else {
-                    let pat_span = pat_span.with_hi(
-                        pat_span.lo()
-                            + BytePos(
-                                (pat_snippet.len() - inner_pat_snippet.trim_start().len()) as u32,
-                            ),
-                    );
-                    (pat_span, String::new(), "borrow")
-                };
-                suggestions.push((
-                    pat_span,
-                    format!("consider removing the {to_remove}"),
-                    suggestion,
-                ));
+                pat_span = Some(pat_sp);
+                binding_spans.push(bind_to.source_info.span);
+            }
+        }
+        let Some(pat_span) = pat_span else { return };
+
+        let hir = self.infcx.tcx.hir();
+        let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) else { return };
+        let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
+        let mut finder = BindingFinder {
+            typeck_results,
+            hir,
+            pat_span,
+            binding_spans,
+            found_pat: false,
+            ref_pat: None,
+            has_adjustments: false,
+            ref_pat_for_binding: Vec::new(),
+            cannot_remove: FxHashSet::default(),
+        };
+        finder.visit_body(body);
+
+        let mut suggestions = Vec::new();
+        for (binding_span, opt_ref_pat) in finder.ref_pat_for_binding {
+            if let Some(ref_pat) = opt_ref_pat
+                && !finder.cannot_remove.contains(&ref_pat.hir_id)
+                && let hir::PatKind::Ref(subpat, mutbl) = ref_pat.kind
+                && let Some(ref_span) = ref_pat.span.trim_end(subpat.span)
+            {
+                let mutable_str = if mutbl.is_mut() { "mutable " } else { "" };
+                let msg = format!("consider removing the {mutable_str}borrow");
+                suggestions.push((ref_span, msg, "".to_string()));
+            } else {
+                let msg = "consider borrowing the pattern binding".to_string();
+                suggestions.push((binding_span.shrink_to_lo(), msg, "ref ".to_string()));
             }
         }
         suggestions.sort_unstable_by_key(|&(span, _, _)| span);
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index d9dba641495..b9a89c20cee 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -40,13 +40,9 @@ include:
   of a delimited expression, delimited expressions are generally combinable,
   regardless of the number of members. Previously only applied with exactly
   one member (except for closures with explicit blocks).
-- When line-breaking an assignment operator, if the left-hand side spans
-  multiple lines, use the base indentation of the last line of the left-hand
-  side to indent the right-hand side.
 - Miscellaneous `rustfmt` bugfixes.
 - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
 - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
-- Format single associated type `where` clauses on the same line if they fit.
 
 ## Rust 2015/2018/2021 style edition
 
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 4f63a632030..171a24cd89d 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -328,31 +328,6 @@ foo_bar
 Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather
 than at other binary operators.
 
-If line-breaking an assignment operator where the left-hand side spans multiple
-lines, use the base indentation of the *last* line of the left-hand side, and
-indent the right-hand side relative to that:
-
-```rust
-impl SomeType {
-    fn method(&mut self) {
-        self.array[array_index as usize]
-            .as_mut()
-            .expect("thing must exist")
-            .extra_info =
-                long_long_long_long_long_long_long_long_long_long_long_long_long_long_long;
-
-        self.array[array_index as usize]
-            .as_mut()
-            .expect("thing must exist")
-            .extra_info = Some(ExtraInfo {
-                parent,
-                count: count as u16,
-                children: children.into_boxed_slice(),
-            });
-    }
-}
-```
-
 ### Casts (`as`)
 
 Format `as` casts like a binary operator. In particular, always include spaces
diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md
index 5ea8b6cd542..be361eee330 100644
--- a/src/doc/style-guide/src/items.md
+++ b/src/doc/style-guide/src/items.md
@@ -295,18 +295,8 @@ Prefer to use single-letter names for generic parameters.
 
 These rules apply for `where` clauses on any item.
 
-If a where clause is short, and appears on a short one-line function
-declaration with no body or on a short type with no `=`, format it on
-the same line as the declaration:
-
-```rust
-fn new(&self) -> Self where Self: Sized;
-
-type Item<'a>: SomeTrait where Self: 'a;
-```
-
-Otherwise, if immediately following a closing bracket of any kind, write the
-keyword `where` on the same line, with a space before it.
+If immediately following a closing bracket of any kind, write the keyword
+`where` on the same line, with a space before it.
 
 Otherwise, put `where` on a new line at the same indentation level. Put each
 component of a `where` clause on its own line, block-indented. Use a trailing
@@ -357,7 +347,7 @@ where
 ```
 
 If a `where` clause is very short, prefer using an inline bound on the type
-parameter if possible.
+parameter.
 
 If a component of a `where` clause does not fit and contains `+`, break it
 before each `+` and block-indent the continuation lines. Put each bound on its
@@ -431,21 +421,9 @@ Format associated types like type aliases. Where an associated type has a
 bound, put a space after the colon but not before:
 
 ```rust
-type Foo: Bar;
+pub type Foo: Bar;
 ```
 
-If an associated type is short, has no `=`, and has a `where` clause with only
-one entry, format the entire type declaration including the `where` clause on
-the same line if it fits:
-
-```rust
-type Item<'a> where Self: 'a;
-type Item<'a>: PartialEq + Send where Self: 'a;
-```
-
-If the associated type has a `=`, or if the `where` clause contains multiple
-entries, format it across multiple lines as with a type alias.
-
 ## extern items
 
 When writing extern items (such as `extern "C" fn`), always specify the ABI.
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index 9792650d37d..e8370a0af02 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -154,6 +154,9 @@ fn check_impl(
             args.insert(0, "--diff".as_ref());
             let _ = py_runner(py_path.as_ref().unwrap(), true, None, "ruff", &args);
         }
+        if res.is_err() && !bless {
+            eprintln!("rerun tidy with `--extra-checks=py:fmt --bless` to reformat Python code");
+        }
         // Rethrow error
         let _ = res?;
     }
diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml
index b5b0052fe61..647a2fd290d 100644
--- a/tests/rustdoc-gui/item-info.goml
+++ b/tests/rustdoc-gui/item-info.goml
@@ -45,3 +45,26 @@ compare-elements-css: (
     "#main-content > .item-info .stab:nth-of-type(2)",
     ["height"],
 )
+
+// Now checking the text color and the links color.
+show-text: true
+include: "utils.goml"
+go-to: "file://" + |DOC_PATH| + "/lib2/trait.Trait.html"
+
+call-function: ("switch-theme", {"theme": "ayu"})
+assert-css: (".item-info .stab", {"color": "rgb(197, 197, 197)"}, ALL)
+assert-css: (".item-info .stab strong", {"color": "rgb(197, 197, 197)"}, ALL)
+assert-css: (".item-info .stab span", {"color": "rgb(197, 197, 197)"}, ALL)
+assert-css: (".item-info .stab a", {"color": "rgb(57, 175, 215)"}, ALL)
+
+call-function: ("switch-theme", {"theme": "dark"})
+assert-css: (".item-info .stab", {"color": "rgb(221, 221, 221)"}, ALL)
+assert-css: (".item-info .stab strong", {"color": "rgb(221, 221, 221)"}, ALL)
+assert-css: (".item-info .stab span", {"color": "rgb(221, 221, 221)"}, ALL)
+assert-css: (".item-info .stab a", {"color": "rgb(210, 153, 29)"}, ALL)
+
+call-function: ("switch-theme", {"theme": "light"})
+assert-css: (".item-info .stab", {"color": "rgb(0, 0, 0)"}, ALL)
+assert-css: (".item-info .stab strong", {"color": "rgb(0, 0, 0)"}, ALL)
+assert-css: (".item-info .stab span", {"color": "rgb(0, 0, 0)"}, ALL)
+assert-css: (".item-info .stab a", {"color": "rgb(56, 115, 173)"}, ALL)
diff --git a/tests/rustdoc/type-alias/deeply-nested-112515.rs b/tests/rustdoc/type-alias/deeply-nested-112515.rs
index 161188ee576..9530feb78de 100644
--- a/tests/rustdoc/type-alias/deeply-nested-112515.rs
+++ b/tests/rustdoc/type-alias/deeply-nested-112515.rs
@@ -1,6 +1,6 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/112515>.
 // It's to ensure that this code doesn't have infinite loop in rustdoc when
-// trying to retrive type alias implementations.
+// trying to retrieve type alias implementations.
 
 // ignore-tidy-linelength
 
diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
index 8d36981b41b..72375eb0b3e 100644
--- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
+++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
@@ -1,6 +1,6 @@
 // Here, there are two types with the same name. One of these has a `derive` annotation, but in the
 // expansion these `impl`s are associated to the the *other* type. There is a suggestion to remove
-// unneded type parameters, but because we're now point at a type with no type parameters, the
+// unneeded type parameters, but because we're now point at a type with no type parameters, the
 // suggestion would suggest removing code from an empty span, which would ICE in nightly.
 //
 // issue: rust-lang/rust#108748
diff --git a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs
index 8eaa0c9194a..cef017e79a4 100644
--- a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs
+++ b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.rs
@@ -1,4 +1,4 @@
-// E0116 caused other unrelated errors, so check no unrelated errors are emmitted.
+// E0116 caused other unrelated errors, so check no unrelated errors are emitted.
 
 fn main() {
     let x = "hello";
diff --git a/tests/ui/indexing/indexing-spans-caller-location.rs b/tests/ui/indexing/indexing-spans-caller-location.rs
index 02d8b853734..b01e3894ac1 100644
--- a/tests/ui/indexing/indexing-spans-caller-location.rs
+++ b/tests/ui/indexing/indexing-spans-caller-location.rs
@@ -20,7 +20,7 @@ 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.
+        // Use the relative number to make it resistant to header changes.
         assert_eq!(caller_line(), self.prev_line + 2);
         &()
     }
diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs
index 7f6758f47f8..3cdb488e7a5 100644
--- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs
+++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.rs
@@ -2,7 +2,7 @@
 
 // Regression test for #107745.
 // Previously need_type_info::update_infer_source will consider expressions originating from
-// macro expressions as candiate "previous sources". This unfortunately can mean that
+// macro expressions as candidate "previous sources". This unfortunately can mean that
 // for macros expansions such as `format!()` internal implementation details can leak, such as:
 //
 // ```
diff --git a/tests/ui/issues/issue-12567.stderr b/tests/ui/issues/issue-12567.stderr
index 3f95f18a967..0b19299ece3 100644
--- a/tests/ui/issues/issue-12567.stderr
+++ b/tests/ui/issues/issue-12567.stderr
@@ -11,14 +11,16 @@ LL |         (&[hd1, ..], &[hd2, ..])
    |                        --- ...and here
    |
    = note: move occurs because these variables have types that don't implement the `Copy` trait
-help: consider borrowing the pattern binding
+help: consider removing the borrow
    |
-LL |         (&[], &[ref hd, ..]) | (&[hd, ..], &[])
-   |                 +++
-help: consider borrowing the pattern binding
+LL -         (&[], &[hd, ..]) | (&[hd, ..], &[])
+LL +         (&[], [hd, ..]) | (&[hd, ..], &[])
+   |
+help: consider removing the borrow
+   |
+LL -         (&[hd1, ..], &[hd2, ..])
+LL +         (&[hd1, ..], [hd2, ..])
    |
-LL |         (&[hd1, ..], &[ref hd2, ..])
-   |                        +++
 
 error[E0508]: cannot move out of type `[T]`, a non-copy slice
   --> $DIR/issue-12567.rs:2:11
@@ -33,14 +35,16 @@ LL |         (&[hd1, ..], &[hd2, ..])
    |            --- ...and here
    |
    = note: move occurs because these variables have types that don't implement the `Copy` trait
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -         (&[], &[hd, ..]) | (&[hd, ..], &[])
+LL +         (&[], [hd, ..]) | (&[hd, ..], &[])
+   |
+help: consider removing the borrow
    |
-LL |         (&[], &[ref hd, ..]) | (&[hd, ..], &[])
-   |                 +++
-help: consider borrowing the pattern binding
+LL -         (&[hd1, ..], &[hd2, ..])
+LL +         ([hd1, ..], &[hd2, ..])
    |
-LL |         (&[ref hd1, ..], &[hd2, ..])
-   |            +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
index 52f4c09e5c0..a8b81394110 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr
@@ -7,10 +7,11 @@ LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
    |                       data moved here
    |                       move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
+LL +     if let Some(Some(x)) = Some(&Some(&mut 0)) {
    |
-LL |     if let Some(&Some(ref x)) = Some(&Some(&mut 0)) {
-   |                       +++
 
 error[E0596]: cannot borrow data in a `&` reference as mutable
   --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:11:10
diff --git a/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.fixed b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.fixed
new file mode 100644
index 00000000000..46b05e4c0a3
--- /dev/null
+++ b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.fixed
@@ -0,0 +1,10 @@
+//@ run-rustfix
+//! diagnostic test for #132806: make sure the suggestion to bind by-reference in patterns doesn't
+//! erroneously remove the wrong `&`
+
+use std::collections::HashMap;
+
+fn main() {
+    let _ = HashMap::<String, i32>::new().iter().filter(|&(_k, &_v)| { true });
+    //~^ ERROR cannot move out of a shared reference
+}
diff --git a/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.rs b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.rs
new file mode 100644
index 00000000000..1312fd6425b
--- /dev/null
+++ b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.rs
@@ -0,0 +1,10 @@
+//@ run-rustfix
+//! diagnostic test for #132806: make sure the suggestion to bind by-reference in patterns doesn't
+//! erroneously remove the wrong `&`
+
+use std::collections::HashMap;
+
+fn main() {
+    let _ = HashMap::<String, i32>::new().iter().filter(|&(&_k, &_v)| { true });
+    //~^ ERROR cannot move out of a shared reference
+}
diff --git a/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.stderr b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.stderr
new file mode 100644
index 00000000000..ff579f93413
--- /dev/null
+++ b/tests/ui/moves/do-not-suggest-removing-wrong-ref-pattern-issue-132806.stderr
@@ -0,0 +1,18 @@
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/do-not-suggest-removing-wrong-ref-pattern-issue-132806.rs:8:58
+   |
+LL |     let _ = HashMap::<String, i32>::new().iter().filter(|&(&_k, &_v)| { true });
+   |                                                          ^^^--^^^^^^
+   |                                                             |
+   |                                                             data moved here
+   |                                                             move occurs because `_k` has type `String`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     let _ = HashMap::<String, i32>::new().iter().filter(|&(&_k, &_v)| { true });
+LL +     let _ = HashMap::<String, i32>::new().iter().filter(|&(_k, &_v)| { true });
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/nll/move-errors.stderr b/tests/ui/nll/move-errors.stderr
index d1384121379..bcb2ab84a23 100644
--- a/tests/ui/nll/move-errors.stderr
+++ b/tests/ui/nll/move-errors.stderr
@@ -209,10 +209,11 @@ LL |         (D(s), &t) => (),
    |                 data moved here
    |                 move occurs because `t` has type `String`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -         (D(s), &t) => (),
+LL +         (D(s), t) => (),
    |
-LL |         (D(s), &ref t) => (),
-   |                 +++
 
 error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:102:11
diff --git a/tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr b/tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr
index 108db6d9e4b..2cf435b1179 100644
--- a/tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr
+++ b/tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr
@@ -9,6 +9,11 @@ LL |         deref!(x) => x,
    |                |
    |                data moved here
    |                move occurs because `x` has type `Struct`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the pattern binding
+   |
+LL |         deref!(ref x) => x,
+   |                +++
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/cant_move_out_of_pattern.rs:17:11
@@ -21,6 +26,11 @@ LL |         deref!(x) => x,
    |                |
    |                data moved here
    |                move occurs because `x` has type `Struct`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the pattern binding
+   |
+LL |         deref!(ref x) => x,
+   |                +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/dont-suggest-ref/simple.rs b/tests/ui/suggestions/dont-suggest-ref/simple.rs
index 1e40e60a1ce..4dea5319264 100644
--- a/tests/ui/suggestions/dont-suggest-ref/simple.rs
+++ b/tests/ui/suggestions/dont-suggest-ref/simple.rs
@@ -219,42 +219,42 @@ pub fn main() {
 
     let (&X(_t),) = (&x.clone(),);
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the borrow
     if let (&Either::One(_t),) = (&e.clone(),) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the borrow
     while let (&Either::One(_t),) = (&e.clone(),) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the borrow
     match (&e.clone(),) {
         //~^ ERROR cannot move
         (&Either::One(_t),)
-        //~^ HELP consider borrowing the pattern binding
+        //~^ HELP consider removing the borrow
         | (&Either::Two(_t),) => (),
     }
     fn f3((&X(_t),): (&X,)) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the borrow
 
     let (&mut X(_t),) = (&mut xm.clone(),);
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the mutable borrow
     if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the mutable borrow
     while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the mutable borrow
     match (&mut em.clone(),) {
         //~^ ERROR cannot move
         (&mut Either::One(_t),) => (),
-        //~^ HELP consider borrowing the pattern binding
+        //~^ HELP consider removing the mutable borrow
         (&mut Either::Two(_t),) => (),
-        //~^ HELP consider borrowing the pattern binding
+        //~^ HELP consider removing the mutable borrow
     }
     fn f4((&mut X(_t),): (&mut X,)) { }
     //~^ ERROR cannot move
-    //~| HELP consider borrowing the pattern binding
+    //~| HELP consider removing the mutable borrow
 
     // move from &Either/&X value
 
diff --git a/tests/ui/suggestions/dont-suggest-ref/simple.stderr b/tests/ui/suggestions/dont-suggest-ref/simple.stderr
index 7d902dbccc4..41571bf9b2c 100644
--- a/tests/ui/suggestions/dont-suggest-ref/simple.stderr
+++ b/tests/ui/suggestions/dont-suggest-ref/simple.stderr
@@ -578,10 +578,11 @@ LL |     let (&X(_t),) = (&x.clone(),);
    |             data moved here
    |             move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -     let (&X(_t),) = (&x.clone(),);
+LL +     let (X(_t),) = (&x.clone(),);
    |
-LL |     let (&X(ref _t),) = (&x.clone(),);
-   |             +++
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:223:34
@@ -592,10 +593,11 @@ LL |     if let (&Either::One(_t),) = (&e.clone(),) { }
    |                          data moved here
    |                          move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -     if let (&Either::One(_t),) = (&e.clone(),) { }
+LL +     if let (Either::One(_t),) = (&e.clone(),) { }
    |
-LL |     if let (&Either::One(ref _t),) = (&e.clone(),) { }
-   |                          +++
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:226:37
@@ -606,10 +608,11 @@ LL |     while let (&Either::One(_t),) = (&e.clone(),) { }
    |                             data moved here
    |                             move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -     while let (&Either::One(_t),) = (&e.clone(),) { }
+LL +     while let (Either::One(_t),) = (&e.clone(),) { }
    |
-LL |     while let (&Either::One(ref _t),) = (&e.clone(),) { }
-   |                             +++
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:229:11
@@ -623,10 +626,11 @@ LL |         (&Either::One(_t),)
    |                       data moved here
    |                       move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -         (&Either::One(_t),)
+LL +         (Either::One(_t),)
    |
-LL |         (&Either::One(ref _t),)
-   |                       +++
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:239:25
@@ -637,10 +641,11 @@ LL |     let (&mut X(_t),) = (&mut xm.clone(),);
    |                 data moved here
    |                 move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the mutable borrow
+   |
+LL -     let (&mut X(_t),) = (&mut xm.clone(),);
+LL +     let (X(_t),) = (&mut xm.clone(),);
    |
-LL |     let (&mut X(ref _t),) = (&mut xm.clone(),);
-   |                 +++
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:242:38
@@ -651,10 +656,11 @@ LL |     if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
    |                              data moved here
    |                              move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the mutable borrow
+   |
+LL -     if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
+LL +     if let (Either::One(_t),) = (&mut em.clone(),) { }
    |
-LL |     if let (&mut Either::One(ref _t),) = (&mut em.clone(),) { }
-   |                              +++
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:245:41
@@ -665,10 +671,11 @@ LL |     while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
    |                                 data moved here
    |                                 move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the mutable borrow
+   |
+LL -     while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
+LL +     while let (Either::One(_t),) = (&mut em.clone(),) { }
    |
-LL |     while let (&mut Either::One(ref _t),) = (&mut em.clone(),) { }
-   |                                 +++
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:248:11
@@ -683,14 +690,16 @@ LL |         (&mut Either::Two(_t),) => (),
    |                           -- ...and here
    |
    = note: move occurs because these variables have types that don't implement the `Copy` trait
-help: consider borrowing the pattern binding
+help: consider removing the mutable borrow
    |
-LL |         (&mut Either::One(ref _t),) => (),
-   |                           +++
-help: consider borrowing the pattern binding
+LL -         (&mut Either::One(_t),) => (),
+LL +         (Either::One(_t),) => (),
+   |
+help: consider removing the mutable borrow
+   |
+LL -         (&mut Either::Two(_t),) => (),
+LL +         (Either::Two(_t),) => (),
    |
-LL |         (&mut Either::Two(ref _t),) => (),
-   |                           +++
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:261:18
@@ -947,10 +956,11 @@ LL |     fn f3((&X(_t),): (&X,)) { }
    |               data moved here
    |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -     fn f3((&X(_t),): (&X,)) { }
+LL +     fn f3((X(_t),): (&X,)) { }
    |
-LL |     fn f3((&X(ref _t),): (&X,)) { }
-   |               +++
 
 error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:255:11
@@ -961,10 +971,11 @@ LL |     fn f4((&mut X(_t),): (&mut X,)) { }
    |                   data moved here
    |                   move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the mutable borrow
+   |
+LL -     fn f4((&mut X(_t),): (&mut X,)) { }
+LL +     fn f4((X(_t),): (&mut X,)) { }
    |
-LL |     fn f4((&mut X(ref _t),): (&mut X,)) { }
-   |                   +++
 
 error[E0507]: cannot move out of `a.a` as enum variant `Some` which is behind a shared reference
   --> $DIR/simple.rs:331:20
diff --git a/tests/ui/suggestions/option-content-move-from-tuple-match.stderr b/tests/ui/suggestions/option-content-move-from-tuple-match.stderr
index 63314acb87c..c93570c579e 100644
--- a/tests/ui/suggestions/option-content-move-from-tuple-match.stderr
+++ b/tests/ui/suggestions/option-content-move-from-tuple-match.stderr
@@ -10,10 +10,11 @@ LL |         (None, &c) => &c.unwrap(),
    |                 data moved here
    |                 move occurs because `c` has type `Option<String>`, which does not implement the `Copy` trait
    |
-help: consider borrowing the pattern binding
+help: consider removing the borrow
+   |
+LL -         (None, &c) => &c.unwrap(),
+LL +         (None, c) => &c.unwrap(),
    |
-LL |         (None, &ref c) => &c.unwrap(),
-   |                 +++
 
 error: aborting due to 1 previous error