diff --git a/.mailmap b/.mailmap index 874a42656c512..18a9e5e44ecc3 100644 --- a/.mailmap +++ b/.mailmap @@ -48,6 +48,7 @@ Andrew Poelstra Anhad Singh Antoine Plaskowski Anton Löfgren +apiraino Araam Borhanian Araam Borhanian Areski Belaid areski @@ -62,7 +63,10 @@ Austin Seipp Ayaz Hafiz Aydin Kim aydin.kim Ayush Mishra +Ashley Mannix asrar +b-naber +b-naber BaoshanPang Barosl Lee Barosl LEE Bastian Kersting @@ -98,6 +102,8 @@ Caleb Cartwright Caleb Jones Noah Lev Noah Lev <37223377+camelid@users.noreply.github.com> +Catherine +Catherine cameron1024 Camille Gillot Carl-Anton Ingmarsson @@ -133,11 +139,13 @@ Clement Miao Clément Renault Cliff Dyer Clinton Ryan +Taylor Cramer ember arlynx Crazycolorz5 csmoe <35686186+csmoe@users.noreply.github.com> Cyryl Płotnicki Damien Schoof +Dan Gohman Dan Robertson Daniel Campoverde Daniel J Rollins @@ -179,10 +187,14 @@ Eduardo Bautista <=> Eduardo Bautista Eduardo Broto Edward Shen +Jacob Finkelman +Jacob Finkelman Elliott Slaughter Elly Fong-Jones Eric Holk Eric Holk +Eric Holk +Eric Holk Eric Holmes Eric Reed Erick Tryzelaar @@ -206,6 +218,7 @@ Felix S. Klock II Félix Saparelli Flaper Fesp Florian Berger +Florian Gilcher Florian Wilkens Florian Wilkens François Mockers Frank Steffahn @@ -240,6 +253,8 @@ Herman J. Radtke III Herman J. Radtke III Hrvoje Nikšić Hsiang-Cheng Yang +Huon Wilson +Huon Wilson Ian Jackson Ian Jackson Ian Jackson @@ -252,9 +267,13 @@ ivan tkachenko J. J. Weber Jack Huey Jacob +Jacob Hoffman-Andrews Jacob Greenfield Jacob Pratt Jacob Pratt +Jake Goulding +Jake Goulding +Jake Goulding Jake Vossen Jakob Degen Jakob Lautrup Nysom @@ -287,6 +306,7 @@ Jerry Hardee Jesús Rubio Jethro Beekman Jian Zeng +Jieyou Xu Jieyou Xu <39484203+jieyouxu@users.noreply.github.com> Jihyun Yu Jihyun Yu jihyun @@ -322,9 +342,12 @@ Josh Holmer Josh Stone Josh Stone Julia Ryan +Jubilee Young <46493976+workingjubilee@users.noreply.github.com> +Jubilee Young Julian Knodt jumbatm <30644300+jumbatm@users.noreply.github.com> Junyoung Cho +Jynn Nelson Jynn Nelson Jynn Nelson Jynn Nelson @@ -385,12 +408,14 @@ Marcell Pardavi Marcus Klaas de Vries Margaret Meyerhofer Mark Mansi +Mark Mansi Mark Rousskov Mark Sinclair Mark Sinclair =Mark Sinclair <=125axel125@gmail.com> Markus Legner Markus Westerlind Markus Martin Carton +Martin Carton Martin Habovštiak Martin Hafskjold Thoresen Martin Nordholts @@ -415,6 +440,7 @@ Melody Horn Mendes mental mibac138 <5672750+mibac138@users.noreply.github.com> +Michael Howell Michael Williams Michael Woerister Michael Woerister @@ -431,6 +457,7 @@ Ms2ger msizanoen1 Mukilan Thiagarajan Nadrieril Feneanar +Nadrieril Feneanar Nadrieril Feneanar NAKASHIMA, Makoto NAKASHIMA, Makoto @@ -447,15 +474,23 @@ Nicholas Bishop Nicholas Bishop Nicholas Nethercote Nicholas Nethercote +Nick Cameron +Nick Fitzgerald Nick Platt Niclas Schwarzlose <15schnic@gmail.com> Nicolas Abram Nicole Mazzuca +Niko Matsakis +Niko Matsakis +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> +Noratrieb <48135649+Noratrieb@users.noreply.github.com> Noratrieb <48135649+Noratrieb@users.noreply.github.com> Nif Ward Nika Layzell +Nikita Popov +Nikita Popov NODA Kai Oğuz Ağcayazı Oğuz Ağcayazı @@ -516,6 +551,7 @@ Ricky Hosfelt Ritiek Malhotra Rob Arnold Rob Arnold Rob Arnold +Robert Collins Robert Foss robertfoss Robert Gawdzik Robert Gawdzik ☢ Robert Habermeier @@ -553,7 +589,15 @@ Simon Sapin Simonas Kazlauskas Simonas Kazlauskas Simonas Kazlauskas Siva Prasad +Skgland <3877590+Skgland@users.noreply.github.com> +Skgland <3877590+Skgland@users.noreply.github.com> +Skgland <3877590+Skgland@users.noreply.github.com> Smittyvb +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> +Sophia June Turner <547158+sophiajt@users.noreply.github.com> +Sophia June Turner <547158+sophiajt@users.noreply.github.com> Srinivas Reddy Thatiparthy Stanislav Tkach startling @@ -586,8 +630,10 @@ Tim Diekmann Tim Hutt Tim JIANG Tim Joseph Dumol +Tim Neumann Timothy Maloney Tomas Koutsky +Tomasz Miąsko Torsten Weber Torsten Weber Trevor Gross @@ -607,7 +653,7 @@ Valerii Lashmanov Vitali Haravy Vitali Haravy Vitaly Shukela Waffle Lapkin -Waffle Lapkin +Waffle Lapkin Wesley Wiser whitequark William Ting diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 4ba6b2e94ec56..beacbdbd3fa7b 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, + /// 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, + } + 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 d9dba641495ab..b9a89c20cee40 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 4f63a632030b4..171a24cd89d73 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 5ea8b6cd54294..be361eee330ac 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 9792650d37d30..e8370a0af027b 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 b5b0052fe6139..647a2fd290de0 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 161188ee5762f..9530feb78de66 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 . // 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 8d36981b41b2f..72375eb0b3e83 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 8eaa0c9194a80..cef017e79a48f 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 02d8b853734e5..b01e3894ac1bd 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 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 7f6758f47f8fe..3cdb488e7a545 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 3f95f18a96743..0b19299ece3ec 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 52f4c09e5c024..a8b813941109c 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 0000000000000..46b05e4c0a3c2 --- /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::::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 0000000000000..1312fd6425b65 --- /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::::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 0000000000000..ff579f934137f --- /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::::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::::new().iter().filter(|&(&_k, &_v)| { true }); +LL + let _ = HashMap::::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 d138412137959..bcb2ab84a239b 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 108db6d9e4b53..2cf435b117999 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 1e40e60a1ce12..4dea5319264ed 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 7d902dbccc4d4..41571bf9b2ca4 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 63314acb87cbf..c93570c579ee7 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`, 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