Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
55020c6
Reverse ordering of `split_{first,last}_chunk` to be `(preceding, last)`
tgross35 Nov 4, 2023
6e8ec85
Make documentation of `slice_first_last_chunk` more consistent
tgross35 Nov 4, 2023
01337bf
Remove `{,r}split_array_ref{,_mut}` methods from slices
tgross35 Nov 4, 2023
8bc123e
Rework doc blocks headings by not turning them into links anymore and…
GuillaumeGomez Feb 25, 2022
d1dd589
Allow links in doc blocks headings
GuillaumeGomez Feb 25, 2022
13b2156
Update rustdoc headings tests
GuillaumeGomez Feb 25, 2022
a4e5e07
Make headings anchor hidden by default and show on hover
GuillaumeGomez Nov 14, 2023
42fcba7
Add tests for headings anchor and links in headings
GuillaumeGomez Nov 14, 2023
d7c5358
Make all headings display the same by creating an anchor right beside…
GuillaumeGomez Dec 5, 2023
bf4a20c
Generate section headings all from one place
GuillaumeGomez Dec 5, 2023
500d6f6
Stabilize `slice_first_last_chunk`
tgross35 Nov 4, 2023
fcaeb45
deps: deduplicate the version of libloading used
nagisa Jan 10, 2024
1dc3ab0
Format sources into the error message when loading codegen backends
nagisa Jan 10, 2024
2ad780e
Clarify that the status of `&!` is undecided
Nadrieril Jan 10, 2024
bf913ad
Simplify use of `ValidityConstraint`
Nadrieril Jan 10, 2024
edb27a3
Make all the empty pattern decisions in `usefulness`
Nadrieril Jan 10, 2024
de77f1a
Simplify empty pattern logic a bit
Nadrieril Jan 10, 2024
d95644d
Simplify empty pattern logic some more
Nadrieril Jan 10, 2024
6f8a944
Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.
kpreid Jan 15, 2024
c48cdfe
Remove unnecessary `let`s and borrowing from `Waker::noop()` usage.
kpreid Jan 15, 2024
a947c4c
Add tests
Nadrieril Jan 5, 2024
d8b72e7
Typecheck never patterns
Nadrieril Jan 5, 2024
ff6fa67
Split-off the passing tests to ensure they pass
Nadrieril Jan 16, 2024
841e9f5
Don't add needs-triage to A-diagnostics
Noratrieb Jan 19, 2024
f9faf16
Suggest .swap() instead of mem::swap() in more cases
sjwang05 Jan 12, 2024
93740f9
Restrict access to the private field of newtype indexes
oli-obk Jan 31, 2023
64461da
Rollup merge of #117561 - tgross35:split-array, r=scottmcm
matthiaskrgr Jan 19, 2024
cad609d
Rollup merge of #117662 - GuillaumeGomez:links-in-headings, r=notriddle
matthiaskrgr Jan 19, 2024
ae09415
Rollup merge of #119815 - nagisa:nagisa/polishes-libloading-use-somew…
matthiaskrgr Jan 19, 2024
2587100
Rollup merge of #119835 - Nadrieril:simplify-empty-logic, r=compiler-…
matthiaskrgr Jan 19, 2024
455382d
Rollup merge of #119984 - kpreid:waker-noop, r=dtolnay
matthiaskrgr Jan 19, 2024
5761c36
Rollup merge of #120009 - Nadrieril:never_patterns_tyck, r=compiler-e…
matthiaskrgr Jan 19, 2024
42e7973
Rollup merge of #120122 - Nilstrieb:Diagnosticstriage, r=oli-obk
matthiaskrgr Jan 19, 2024
c851150
Rollup merge of #120126 - sjwang05:issue-102269, r=compiler-errors
matthiaskrgr Jan 19, 2024
ee12697
Rollup merge of #120134 - oli-obk:newtype_index_private_field, r=comp…
matthiaskrgr Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Suggest .swap() instead of mem::swap() in more cases
  • Loading branch information
sjwang05 committed Jan 19, 2024
commit f9faf161817eef2b885bd47908ceaeef675ea72f
99 changes: 92 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore-tidy-filelength

use either::Either;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
Expand All @@ -24,6 +26,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
use rustc_trait_selection::traits::ObligationCtxt;
use std::iter;

Expand Down Expand Up @@ -1295,14 +1298,96 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place: Place<'tcx>,
borrowed_place: Place<'tcx>,
) {
if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) =
(&place.projection[..], &borrowed_place.projection[..])
let tcx = self.infcx.tcx;
let hir = tcx.hir();

if let ([ProjectionElem::Index(index1)], [ProjectionElem::Index(index2)])
| (
[ProjectionElem::Deref, ProjectionElem::Index(index1)],
[ProjectionElem::Deref, ProjectionElem::Index(index2)],
) = (&place.projection[..], &borrowed_place.projection[..])
{
err.help(
"consider using `.split_at_mut(position)` or similar method to obtain \
two mutable non-overlapping sub-slices",
)
.help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
let mut note_default_suggestion = || {
err.help(
"consider using `.split_at_mut(position)` or similar method to obtain \
two mutable non-overlapping sub-slices",
)
.help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
};

let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else {
note_default_suggestion();
return;
};

let mut expr_finder =
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index1) = expr_finder.result else {
note_default_suggestion();
return;
};

expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index2) = expr_finder.result else {
note_default_suggestion();
return;
};

let sm = tcx.sess.source_map();

let Ok(index1_str) = sm.span_to_snippet(index1.span) else {
note_default_suggestion();
return;
};

let Ok(index2_str) = sm.span_to_snippet(index2.span) else {
note_default_suggestion();
return;
};

let Some(object) = hir.parent_id_iter(index1.hir_id).find_map(|id| {
if let hir::Node::Expr(expr) = tcx.hir_node(id)
&& let hir::ExprKind::Index(obj, ..) = expr.kind
{
Some(obj)
} else {
None
}
}) else {
note_default_suggestion();
return;
};

let Ok(obj_str) = sm.span_to_snippet(object.span) else {
note_default_suggestion();
return;
};

let Some(swap_call) = hir.parent_id_iter(object.hir_id).find_map(|id| {
if let hir::Node::Expr(call) = tcx.hir_node(id)
&& let hir::ExprKind::Call(callee, ..) = call.kind
&& let hir::ExprKind::Path(qpath) = callee.kind
&& let hir::QPath::Resolved(None, res) = qpath
&& let hir::def::Res::Def(_, did) = res.res
&& tcx.is_diagnostic_item(sym::mem_swap, did)
{
Some(call)
} else {
None
}
}) else {
note_default_suggestion();
return;
};

err.span_suggestion(
swap_call.span,
"use `.swap()` to swap elements at the specified indices instead",
format!("{obj_str}.swap({index1_str}, {index2_str})"),
Applicability::MachineApplicable,
);
}
}

Expand Down
9 changes: 9 additions & 0 deletions tests/ui/suggestions/suggest-slice-swap.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-rustfix
#![allow(dead_code)]

fn swap(arr: &mut [u32; 2]) {
arr.swap(1, 0);
//~^ ERROR cannot borrow `arr[_]` as mutable more than once at a time
}

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/suggestions/suggest-slice-swap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-rustfix
#![allow(dead_code)]

fn swap(arr: &mut [u32; 2]) {
std::mem::swap(&mut arr[0], &mut arr[1]);
//~^ ERROR cannot borrow `arr[_]` as mutable more than once at a time
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/suggestions/suggest-slice-swap.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0499]: cannot borrow `arr[_]` as mutable more than once at a time
--> $DIR/suggest-slice-swap.rs:5:33
|
LL | std::mem::swap(&mut arr[0], &mut arr[1]);
| -------------- ----------- ^^^^^^^^^^^ second mutable borrow occurs here
| | |
| | first mutable borrow occurs here
| first borrow later used by call
|
help: use `.swap()` to swap elements at the specified indices instead
|
LL | arr.swap(1, 0);
| ~~~~~~~~~~~~~~

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0499`.