Add help for trying to do C-like pointer arithmetics

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2023-06-04 10:18:09 +08:00
parent 8b35c0bb0f
commit 63d643da84
No known key found for this signature in database
GPG key ID: C5FD5D32014FDB47
5 changed files with 135 additions and 0 deletions

View file

@ -2870,6 +2870,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
}
if base_t.is_unsafe_ptr() && idx_t.is_integral() {
err.multipart_suggestion(
"consider using `wrapping_add` or `add` for indexing into raw pointer",
vec![
(base.span.between(idx.span), ".wrapping_add(".to_owned()),
(
idx.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
")".to_owned(),
),
],
Applicability::MaybeIncorrect,
);
}
let reported = err.emit();
self.tcx.ty_error(reported)
}

View file

@ -521,6 +521,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
// Suggest using `add`, `offset` or `offset_from` for pointer - {integer},
// pointer + {integer} or pointer - pointer.
if op.span.can_be_used_for_suggestions() {
match op.node {
hir::BinOpKind::Add if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() => {
err.multipart_suggestion(
"consider using `wrapping_add` or `add` for pointer + {integer}",
vec![
(
lhs_expr.span.between(rhs_expr.span),
".wrapping_add(".to_owned(),
),
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
],
Applicability::MaybeIncorrect,
);
}
hir::BinOpKind::Sub => {
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
err.multipart_suggestion(
"consider using `wrapping_sub` or `sub` for pointer - {integer}",
vec![
(lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
],
Applicability::MaybeIncorrect
);
}
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
err.multipart_suggestion(
"consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
vec![
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
(lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
],
Applicability::MaybeIncorrect
);
}
}
_ => {}
}
}
let reported = err.emit();
self.tcx.ty_error(reported)
}