Skip to content

Commit dbaa4e2

Browse files
committed
Only suggest split_at_mut on indexing borrowck errors for std types
1 parent 386236f commit dbaa4e2

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+22-8
Original file line numberDiff line numberDiff line change
@@ -2018,12 +2018,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
20182018
) {
20192019
let tcx = self.infcx.tcx;
20202020
let hir = tcx.hir();
2021+
2022+
let has_split_at_mut = |ty: Ty<'tcx>| {
2023+
let ty = ty.peel_refs();
2024+
match ty.kind() {
2025+
ty::Array(..) | ty::Slice(..) => true,
2026+
ty::Adt(def, _) if tcx.get_diagnostic_item(sym::Vec) == Some(def.did()) => true,
2027+
_ if ty == tcx.types.str_ => true,
2028+
_ => false,
2029+
}
2030+
};
20212031
if let ([ProjectionElem::Index(index1)], [ProjectionElem::Index(index2)])
20222032
| (
20232033
[ProjectionElem::Deref, ProjectionElem::Index(index1)],
20242034
[ProjectionElem::Deref, ProjectionElem::Index(index2)],
20252035
) = (&place.projection[..], &borrowed_place.projection[..])
20262036
{
2037+
let decl1 = &self.body.local_decls[*index1];
2038+
let decl2 = &self.body.local_decls[*index2];
2039+
20272040
let mut note_default_suggestion = || {
20282041
err.help(
20292042
"consider using `.split_at_mut(position)` or similar method to obtain two \
@@ -2035,14 +2048,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
20352048
);
20362049
};
20372050

2038-
let Some(index1) = self.find_expr(self.body.local_decls[*index1].source_info.span)
2039-
else {
2051+
let Some(index1) = self.find_expr(decl1.source_info.span) else {
20402052
note_default_suggestion();
20412053
return;
20422054
};
20432055

2044-
let Some(index2) = self.find_expr(self.body.local_decls[*index2].source_info.span)
2045-
else {
2056+
let Some(index2) = self.find_expr(decl2.source_info.span) else {
20462057
note_default_suggestion();
20472058
return;
20482059
};
@@ -2102,16 +2113,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21022113
);
21032114
return;
21042115
}
2116+
let place_ty = PlaceRef::ty(&place.as_ref(), self.body, tcx).ty;
2117+
let borrowed_place_ty = PlaceRef::ty(&borrowed_place.as_ref(), self.body, tcx).ty;
2118+
if !has_split_at_mut(place_ty) && !has_split_at_mut(borrowed_place_ty) {
2119+
// Only mention `split_at_mut` on `Vec`, array and slices.
2120+
return;
2121+
}
21052122
let Some(index1) = self.find_expr(span) else { return };
21062123
let hir::Node::Expr(parent) = tcx.parent_hir_node(index1.hir_id) else { return };
21072124
let hir::ExprKind::Index(..) = parent.kind else { return };
21082125
let Some(index2) = self.find_expr(issued_span) else { return };
21092126
let hir::Node::Expr(parent) = tcx.parent_hir_node(index2.hir_id) else { return };
21102127
let hir::ExprKind::Index(..) = parent.kind else { return };
2111-
err.help(
2112-
"use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping \
2113-
sub-slices",
2114-
);
2128+
err.help("use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices");
21152129
}
21162130

21172131
/// Suggest using `while let` for call `next` on an iterator in a for loop.

tests/ui/borrowck/borrowck-overloaded-index-autoderef.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ LL | let q = &mut f[&s];
1717
| ^ second mutable borrow occurs here
1818
LL | p.use_mut();
1919
| - first borrow later used here
20-
|
21-
= help: use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
2220

2321
error[E0499]: cannot borrow `f.foo` as mutable more than once at a time
2422
--> $DIR/borrowck-overloaded-index-autoderef.rs:53:18
@@ -29,8 +27,6 @@ LL | let q = &mut f.foo[&s];
2927
| ^^^^^ second mutable borrow occurs here
3028
LL | p.use_mut();
3129
| - first borrow later used here
32-
|
33-
= help: use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
3430

3531
error[E0502]: cannot borrow `f.foo` as mutable because it is also borrowed as immutable
3632
--> $DIR/borrowck-overloaded-index-autoderef.rs:65:18

tests/ui/suggestions/suggest-split-at-mut.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ LL | let b = &mut foo[2..];
2121
LL | a[0] = 5;
2222
| ---- first borrow later used here
2323
|
24-
= help: use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
24+
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
2525

2626
error: aborting due to 2 previous errors
2727

0 commit comments

Comments
 (0)