Skip to content

Commit 8c586cc

Browse files
committed
Only suggest split_at_mut on indexing borrowck errors for std types
1 parent 7af17f7 commit 8c586cc

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,12 +1981,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19811981
) {
19821982
let tcx = self.infcx.tcx;
19831983
let hir = tcx.hir();
1984+
1985+
let has_split_at_mut = |ty: Ty<'tcx>| {
1986+
let ty = ty.peel_refs();
1987+
match ty.kind() {
1988+
ty::Array(..) | ty::Slice(..) => true,
1989+
ty::Adt(def, _) if tcx.get_diagnostic_item(sym::Vec) == Some(def.did()) => true,
1990+
_ if ty == tcx.types.str_ => true,
1991+
_ => false,
1992+
}
1993+
};
19841994
if let ([ProjectionElem::Index(index1)], [ProjectionElem::Index(index2)])
19851995
| (
19861996
[ProjectionElem::Deref, ProjectionElem::Index(index1)],
19871997
[ProjectionElem::Deref, ProjectionElem::Index(index2)],
19881998
) = (&place.projection[..], &borrowed_place.projection[..])
19891999
{
2000+
let decl1 = &self.body.local_decls[*index1];
2001+
let decl2 = &self.body.local_decls[*index2];
2002+
19902003
let mut note_default_suggestion = || {
19912004
err.help(
19922005
"consider using `.split_at_mut(position)` or similar method to obtain two \
@@ -1998,14 +2011,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19982011
);
19992012
};
20002013

2001-
let Some(index1) = self.find_expr(self.body.local_decls[*index1].source_info.span)
2002-
else {
2014+
let Some(index1) = self.find_expr(decl1.source_info.span) else {
20032015
note_default_suggestion();
20042016
return;
20052017
};
20062018

2007-
let Some(index2) = self.find_expr(self.body.local_decls[*index2].source_info.span)
2008-
else {
2019+
let Some(index2) = self.find_expr(decl2.source_info.span) else {
20092020
note_default_suggestion();
20102021
return;
20112022
};
@@ -2065,16 +2076,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
20652076
);
20662077
return;
20672078
}
2079+
let place_ty = PlaceRef::ty(&place.as_ref(), self.body, tcx).ty;
2080+
let borrowed_place_ty = PlaceRef::ty(&borrowed_place.as_ref(), self.body, tcx).ty;
2081+
if !has_split_at_mut(place_ty) && !has_split_at_mut(borrowed_place_ty) {
2082+
// Only mention `split_at_mut` on `Vec`, array and slices.
2083+
return;
2084+
}
20682085
let Some(index1) = self.find_expr(span) else { return };
20692086
let hir::Node::Expr(parent) = tcx.parent_hir_node(index1.hir_id) else { return };
20702087
let hir::ExprKind::Index(..) = parent.kind else { return };
20712088
let Some(index2) = self.find_expr(issued_span) else { return };
20722089
let hir::Node::Expr(parent) = tcx.parent_hir_node(index2.hir_id) else { return };
20732090
let hir::ExprKind::Index(..) = parent.kind else { return };
2074-
err.help(
2075-
"use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping \
2076-
sub-slices",
2077-
);
2091+
err.help("use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices");
20782092
}
20792093

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

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

Lines changed: 0 additions & 4 deletions
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

Lines changed: 1 addition & 1 deletion
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)