Skip to content

Commit fd0a331

Browse files
committed
Auto merge of #112261 - jieyouxu:c-like-ptr-arithmetics-diagnostics, r=WaffleLapkin
Add help for trying to do C-like pointer arithmetics This PR adds help messages for these cases: ```rust fn main() { let ptr1: *const u32 = std::ptr::null(); let ptr2: *const u32 = std::ptr::null(); let a = ptr1 + 5; let b = ptr1 - 5; let c = ptr2 - ptr1; let d = ptr1[5]; } ``` ### Current Output ``` error[E0369]: cannot add `{integer}` to `*const u32` --> tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs:4:18 | 4 | let a = ptr1 + 5; //~ ERROR cannot add | ---- ^ - {integer} | | | *const u32 error[E0369]: cannot subtract `{integer}` from `*const u32` --> tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs:5:18 | 5 | let b = ptr1 - 5; //~ ERROR cannot subtract | ---- ^ - {integer} | | | *const u32 error[E0369]: cannot subtract `*const u32` from `*const u32` --> tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs:6:18 | 6 | let c = ptr2 - ptr1; //~ ERROR cannot subtract | ---- ^ ---- *const u32 | | | *const u32 error[E0608]: cannot index into a value of type `*const u32` --> tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs:7:13 | 7 | let d = ptr1[5]; //~ ERROR cannot index | ^^^^^^^ error: aborting due to 4 previous errors ``` ### Output After This PR ``` error[E0369]: cannot add `{integer}` to `*const u32` --> $DIR/issue-112252-ptr-arithmetics-help.rs:6:20 | LL | let _a = _ptr1 + 5; | ------^-- | | | | | {integer} | *const u32 | help: consider using `wrapping_add` or `add` for pointer + {integer}: `_ptr1.wrapping_add(5)` error[E0369]: cannot subtract `{integer}` from `*const u32` --> $DIR/issue-112252-ptr-arithmetics-help.rs:7:20 | LL | let _b = _ptr1 - 5; | ------^-- | | | | | {integer} | *const u32 | help: consider using `offset` for pointer - {integer}: `unsafe { _ptr1.offset(-5) }` error[E0369]: cannot subtract `*const u32` from `*const u32` --> $DIR/issue-112252-ptr-arithmetics-help.rs:8:20 | LL | let _c = _ptr2 - _ptr1; | ------^------ | | | | | *const u32 | *const u32 | help: consider using `offset_from` for pointer - pointer if the pointers point to the same allocation: `_ptr2.offset_from(_ptr1)` error[E0608]: cannot index into a value of type `*const u32` --> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14 | LL | let _d = _ptr1[5]; | ^^^^^^^^ | help: consider using `wrapping_add` or `add` for indexing into raw pointer | LL | let _d = _ptr1.wrapping_add(5); | ~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 4 previous errors ``` Closes #112252.
2 parents 77dba22 + 63d643d commit fd0a331

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+15
Original file line numberDiff line numberDiff line change
@@ -2871,6 +2871,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28712871
);
28722872
}
28732873
}
2874+
2875+
if base_t.is_unsafe_ptr() && idx_t.is_integral() {
2876+
err.multipart_suggestion(
2877+
"consider using `wrapping_add` or `add` for indexing into raw pointer",
2878+
vec![
2879+
(base.span.between(idx.span), ".wrapping_add(".to_owned()),
2880+
(
2881+
idx.span.shrink_to_hi().until(expr.span.shrink_to_hi()),
2882+
")".to_owned(),
2883+
),
2884+
],
2885+
Applicability::MaybeIncorrect,
2886+
);
2887+
}
2888+
28742889
let reported = err.emit();
28752890
self.tcx.ty_error(reported)
28762891
}

compiler/rustc_hir_typeck/src/op.rs

+46
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
521521
}
522522
}
523523
}
524+
525+
// Suggest using `add`, `offset` or `offset_from` for pointer - {integer},
526+
// pointer + {integer} or pointer - pointer.
527+
if op.span.can_be_used_for_suggestions() {
528+
match op.node {
529+
hir::BinOpKind::Add if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() => {
530+
err.multipart_suggestion(
531+
"consider using `wrapping_add` or `add` for pointer + {integer}",
532+
vec![
533+
(
534+
lhs_expr.span.between(rhs_expr.span),
535+
".wrapping_add(".to_owned(),
536+
),
537+
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
538+
],
539+
Applicability::MaybeIncorrect,
540+
);
541+
}
542+
hir::BinOpKind::Sub => {
543+
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_integral() {
544+
err.multipart_suggestion(
545+
"consider using `wrapping_sub` or `sub` for pointer - {integer}",
546+
vec![
547+
(lhs_expr.span.between(rhs_expr.span), ".wrapping_sub(".to_owned()),
548+
(rhs_expr.span.shrink_to_hi(), ")".to_owned()),
549+
],
550+
Applicability::MaybeIncorrect
551+
);
552+
}
553+
554+
if lhs_ty.is_unsafe_ptr() && rhs_ty.is_unsafe_ptr() {
555+
err.multipart_suggestion(
556+
"consider using `offset_from` for pointer - pointer if the pointers point to the same allocation",
557+
vec![
558+
(lhs_expr.span.shrink_to_lo(), "unsafe { ".to_owned()),
559+
(lhs_expr.span.between(rhs_expr.span), ".offset_from(".to_owned()),
560+
(rhs_expr.span.shrink_to_hi(), ") }".to_owned()),
561+
],
562+
Applicability::MaybeIncorrect
563+
);
564+
}
565+
}
566+
_ => {}
567+
}
568+
}
569+
524570
let reported = err.emit();
525571
self.tcx.ty_error(reported)
526572
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// run-rustfix
2+
3+
fn main() {
4+
let _ptr1: *const u32 = std::ptr::null();
5+
let _ptr2: *const u32 = std::ptr::null();
6+
let _a = _ptr1.wrapping_add(5); //~ ERROR cannot add
7+
let _b = _ptr1.wrapping_sub(5); //~ ERROR cannot subtract
8+
let _c = unsafe { _ptr2.offset_from(_ptr1) }; //~ ERROR cannot subtract
9+
let _d = _ptr1.wrapping_add(5); //~ ERROR cannot index
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// run-rustfix
2+
3+
fn main() {
4+
let _ptr1: *const u32 = std::ptr::null();
5+
let _ptr2: *const u32 = std::ptr::null();
6+
let _a = _ptr1 + 5; //~ ERROR cannot add
7+
let _b = _ptr1 - 5; //~ ERROR cannot subtract
8+
let _c = _ptr2 - _ptr1; //~ ERROR cannot subtract
9+
let _d = _ptr1[5]; //~ ERROR cannot index
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error[E0369]: cannot add `{integer}` to `*const u32`
2+
--> $DIR/issue-112252-ptr-arithmetics-help.rs:6:20
3+
|
4+
LL | let _a = _ptr1 + 5;
5+
| ----- ^ - {integer}
6+
| |
7+
| *const u32
8+
|
9+
help: consider using `wrapping_add` or `add` for pointer + {integer}
10+
|
11+
LL | let _a = _ptr1.wrapping_add(5);
12+
| ~~~~~~~~~~~~~~ +
13+
14+
error[E0369]: cannot subtract `{integer}` from `*const u32`
15+
--> $DIR/issue-112252-ptr-arithmetics-help.rs:7:20
16+
|
17+
LL | let _b = _ptr1 - 5;
18+
| ----- ^ - {integer}
19+
| |
20+
| *const u32
21+
|
22+
help: consider using `wrapping_sub` or `sub` for pointer - {integer}
23+
|
24+
LL | let _b = _ptr1.wrapping_sub(5);
25+
| ~~~~~~~~~~~~~~ +
26+
27+
error[E0369]: cannot subtract `*const u32` from `*const u32`
28+
--> $DIR/issue-112252-ptr-arithmetics-help.rs:8:20
29+
|
30+
LL | let _c = _ptr2 - _ptr1;
31+
| ----- ^ ----- *const u32
32+
| |
33+
| *const u32
34+
|
35+
help: consider using `offset_from` for pointer - pointer if the pointers point to the same allocation
36+
|
37+
LL | let _c = unsafe { _ptr2.offset_from(_ptr1) };
38+
| ++++++++ ~~~~~~~~~~~~~ +++
39+
40+
error[E0608]: cannot index into a value of type `*const u32`
41+
--> $DIR/issue-112252-ptr-arithmetics-help.rs:9:14
42+
|
43+
LL | let _d = _ptr1[5];
44+
| ^^^^^^^^
45+
|
46+
help: consider using `wrapping_add` or `add` for indexing into raw pointer
47+
|
48+
LL | let _d = _ptr1.wrapping_add(5);
49+
| ~~~~~~~~~~~~~~ ~
50+
51+
error: aborting due to 4 previous errors
52+
53+
Some errors have detailed explanations: E0369, E0608.
54+
For more information about an error, try `rustc --explain E0369`.

0 commit comments

Comments
 (0)