Skip to content

Commit 9d69c35

Browse files
committed
Add diagnostics and suggestions for raw pointer arithmetic assignments
1 parent 299877e commit 9d69c35

File tree

9 files changed

+127
-6
lines changed

9 files changed

+127
-6
lines changed

compiler/rustc_hir_typeck/src/op.rs

+51-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
234234
// us do better coercions than we would be able to do otherwise,
235235
// particularly for things like `String + &String`.
236236
let rhs_ty_var = self.next_ty_var(rhs_expr.span);
237-
238237
let result = self.lookup_op_method(
239238
(lhs_expr, lhs_ty),
240239
Some((rhs_expr, rhs_ty_var)),
@@ -698,6 +697,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
698697
}
699698
}
700699

700+
let lhs_name_str = match lhs_expr.kind {
701+
hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => {
702+
path.segments.last().map_or("_".to_string(), |s| s.ident.to_string())
703+
}
704+
_ => self
705+
.tcx
706+
.sess
707+
.source_map()
708+
.span_to_snippet(lhs_expr.span)
709+
.unwrap_or("_".to_string()),
710+
};
711+
712+
if op.span().can_be_used_for_suggestions() {
713+
match op {
714+
Op::AssignOp(Spanned { node: hir::AssignOpKind::AddAssign, .. })
715+
if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() =>
716+
{
717+
err.multipart_suggestion(
718+
"consider using `add` or `wrapping_add` to do pointer arithmetic",
719+
vec![
720+
(lhs_expr.span.shrink_to_lo(), format!("{} = ", lhs_name_str)),
721+
(
722+
lhs_expr.span.between(rhs_expr.span),
723+
".wrapping_add(".to_owned(),
724+
),
725+
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
726+
],
727+
Applicability::MaybeIncorrect,
728+
);
729+
}
730+
Op::AssignOp(Spanned { node: hir::AssignOpKind::SubAssign, .. }) => {
731+
if lhs_ty.is_raw_ptr() && rhs_ty.is_integral() {
732+
err.multipart_suggestion(
733+
"consider using `sub` or `wrapping_sub` to do pointer arithmetic",
734+
vec![
735+
(lhs_expr.span.shrink_to_lo(), format!("{} = ", lhs_name_str)),
736+
(
737+
lhs_expr.span.between(rhs_expr.span),
738+
".wrapping_sub(".to_owned(),
739+
740+
),
741+
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
742+
],
743+
Applicability::MaybeIncorrect,
744+
);
745+
}
746+
}
747+
_ => {}
748+
}
749+
}
750+
701751
let reported = err.emit();
702752
Ty::new_error(self.tcx, reported)
703753
}

src/doc/nomicon

Submodule nomicon updated 1 file

src/doc/reference

Submodule reference updated 89 files
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ run-rustfix
2+
#![allow(dead_code)]
3+
#![allow(unused_variables)]
4+
#![allow(unused_assignments)]
5+
6+
fn test_add_assign_raw_pointer() {
7+
let mut arr = [0u8; 10];
8+
let mut _ptr = arr.as_mut_ptr();
9+
10+
_ptr = _ptr.wrapping_add(2); //~ ERROR binary assignment operation `+=` cannot be applied to type `*mut u8` [E0368]
11+
}
12+
13+
fn test_sub_assign_raw_pointer() {
14+
let mut arr = [0u8; 10];
15+
let mut _ptr = arr.as_mut_ptr();
16+
17+
_ptr = _ptr.wrapping_sub(2); //~ ERROR binary assignment operation `-=` cannot be applied to type `*mut u8` [E0368]
18+
}
19+
20+
fn main() {}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//@ run-rustfix
2+
#![allow(dead_code)]
3+
#![allow(unused_variables)]
4+
#![allow(unused_assignments)]
5+
6+
fn test_add_assign_raw_pointer() {
7+
let mut arr = [0u8; 10];
8+
let mut _ptr = arr.as_mut_ptr();
9+
10+
_ptr += 2; //~ ERROR binary assignment operation `+=` cannot be applied to type `*mut u8` [E0368]
11+
}
12+
13+
fn test_sub_assign_raw_pointer() {
14+
let mut arr = [0u8; 10];
15+
let mut _ptr = arr.as_mut_ptr();
16+
17+
_ptr -= 2; //~ ERROR binary assignment operation `-=` cannot be applied to type `*mut u8` [E0368]
18+
}
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0368]: binary assignment operation `+=` cannot be applied to type `*mut u8`
2+
--> $DIR/pointer-arith-assign.rs:10:5
3+
|
4+
LL | _ptr += 2;
5+
| ----^^^^^
6+
| |
7+
| cannot use `+=` on type `*mut u8`
8+
|
9+
help: consider using `add` or `wrapping_add` to do pointer arithmetic
10+
|
11+
LL - _ptr += 2;
12+
LL + _ptr = _ptr.wrapping_add(2);
13+
|
14+
15+
error[E0368]: binary assignment operation `-=` cannot be applied to type `*mut u8`
16+
--> $DIR/pointer-arith-assign.rs:17:5
17+
|
18+
LL | _ptr -= 2;
19+
| ----^^^^^
20+
| |
21+
| cannot use `-=` on type `*mut u8`
22+
|
23+
help: consider using `sub` or `wrapping_sub` to do pointer arithmetic
24+
|
25+
LL - _ptr -= 2;
26+
LL + _ptr = _ptr.wrapping_sub(2);
27+
|
28+
29+
error: aborting due to 2 previous errors
30+
31+
For more information about this error, try `rustc --explain E0368`.

0 commit comments

Comments
 (0)