Add diagnostics and suggestions for raw pointer arithmetic assignments
This commit is contained in:
parent
299877e280
commit
834e476a0c
4 changed files with 122 additions and 1 deletions
|
@ -234,7 +234,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// us do better coercions than we would be able to do otherwise,
|
||||
// particularly for things like `String + &String`.
|
||||
let rhs_ty_var = self.next_ty_var(rhs_expr.span);
|
||||
|
||||
let result = self.lookup_op_method(
|
||||
(lhs_expr, lhs_ty),
|
||||
Some((rhs_expr, rhs_ty_var)),
|
||||
|
@ -698,6 +697,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let lhs_name_str = match lhs_expr.kind {
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => {
|
||||
path.segments.last().map_or("_".to_string(), |s| s.ident.to_string())
|
||||
}
|
||||
_ => self
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_snippet(lhs_expr.span)
|
||||
.unwrap_or("_".to_string()),
|
||||
};
|
||||
|
||||
if op.span().can_be_used_for_suggestions() {
|
||||
match op {
|
||||
Op::AssignOp(Spanned { node: hir::AssignOpKind::AddAssign, .. })
|
||||
if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() =>
|
||||
{
|
||||
err.multipart_suggestion(
|
||||
"consider using `add` or `wrapping_add` to do pointer arithmetic",
|
||||
vec![
|
||||
(lhs_expr.span.shrink_to_lo(), format!("{} = ", lhs_name_str)),
|
||||
(
|
||||
lhs_expr.span.between(rhs_expr.span),
|
||||
".wrapping_add(".to_owned(),
|
||||
),
|
||||
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
Op::AssignOp(Spanned { node: hir::AssignOpKind::SubAssign, .. }) => {
|
||||
if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() {
|
||||
err.multipart_suggestion(
|
||||
"consider using `sub` or `wrapping_sub` to do pointer arithmetic",
|
||||
vec![
|
||||
(lhs_expr.span.shrink_to_lo(), format!("{} = ", lhs_name_str)),
|
||||
(
|
||||
lhs_expr.span.between(rhs_expr.span),
|
||||
".wrapping_sub(".to_owned(),
|
||||
|
||||
),
|
||||
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let reported = err.emit();
|
||||
Ty::new_error(self.tcx, reported)
|
||||
}
|
||||
|
|
20
tests/ui/typeck/pointer-arith-assign.fixed
Normal file
20
tests/ui/typeck/pointer-arith-assign.fixed
Normal file
|
@ -0,0 +1,20 @@
|
|||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
fn test_add_assign_raw_pointer() {
|
||||
let mut arr = [0u8; 10];
|
||||
let mut _ptr = arr.as_mut_ptr();
|
||||
|
||||
_ptr = _ptr.wrapping_add(2); //~ ERROR binary assignment operation `+=` cannot be applied to type `*mut u8` [E0368]
|
||||
}
|
||||
|
||||
fn test_sub_assign_raw_pointer() {
|
||||
let mut arr = [0u8; 10];
|
||||
let mut _ptr = arr.as_mut_ptr();
|
||||
|
||||
_ptr = _ptr.wrapping_sub(2); //~ ERROR binary assignment operation `-=` cannot be applied to type `*mut u8` [E0368]
|
||||
}
|
||||
|
||||
fn main() {}
|
20
tests/ui/typeck/pointer-arith-assign.rs
Normal file
20
tests/ui/typeck/pointer-arith-assign.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
//@ run-rustfix
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
fn test_add_assign_raw_pointer() {
|
||||
let mut arr = [0u8; 10];
|
||||
let mut _ptr = arr.as_mut_ptr();
|
||||
|
||||
_ptr += 2; //~ ERROR binary assignment operation `+=` cannot be applied to type `*mut u8` [E0368]
|
||||
}
|
||||
|
||||
fn test_sub_assign_raw_pointer() {
|
||||
let mut arr = [0u8; 10];
|
||||
let mut _ptr = arr.as_mut_ptr();
|
||||
|
||||
_ptr -= 2; //~ ERROR binary assignment operation `-=` cannot be applied to type `*mut u8` [E0368]
|
||||
}
|
||||
|
||||
fn main() {}
|
31
tests/ui/typeck/pointer-arith-assign.stderr
Normal file
31
tests/ui/typeck/pointer-arith-assign.stderr
Normal file
|
@ -0,0 +1,31 @@
|
|||
error[E0368]: binary assignment operation `+=` cannot be applied to type `*mut u8`
|
||||
--> $DIR/pointer-arith-assign.rs:10:5
|
||||
|
|
||||
LL | _ptr += 2;
|
||||
| ----^^^^^
|
||||
| |
|
||||
| cannot use `+=` on type `*mut u8`
|
||||
|
|
||||
help: consider using `add` or `wrapping_add` to do pointer arithmetic
|
||||
|
|
||||
LL - _ptr += 2;
|
||||
LL + _ptr = _ptr.wrapping_add(2);
|
||||
|
|
||||
|
||||
error[E0368]: binary assignment operation `-=` cannot be applied to type `*mut u8`
|
||||
--> $DIR/pointer-arith-assign.rs:17:5
|
||||
|
|
||||
LL | _ptr -= 2;
|
||||
| ----^^^^^
|
||||
| |
|
||||
| cannot use `-=` on type `*mut u8`
|
||||
|
|
||||
help: consider using `sub` or `wrapping_sub` to do pointer arithmetic
|
||||
|
|
||||
LL - _ptr -= 2;
|
||||
LL + _ptr = _ptr.wrapping_sub(2);
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0368`.
|
Loading…
Add table
Add a link
Reference in a new issue