diff options
| author | bors <bors@rust-lang.org> | 2023-06-12 07:15:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-06-12 07:15:19 +0000 |
| commit | fd0a3313f7a64cb16533030e49a271db449368c3 (patch) | |
| tree | 0bef4734e29477f755f2e0e2c266d2736d561bee | |
| parent | 77dba225c1048e5585b2cdefb7f8588bd2d2741b (diff) | |
| parent | 63d643da841bedd6b855f617edecc0b13c0cd71e (diff) | |
| download | rust-fd0a3313f7a64cb16533030e49a271db449368c3.tar.gz rust-fd0a3313f7a64cb16533030e49a271db449368c3.zip | |
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.
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/op.rs | 46 | ||||
| -rw-r--r-- | tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed | 10 | ||||
| -rw-r--r-- | tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs | 10 | ||||
| -rw-r--r-- | tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr | 54 |
5 files changed, 135 insertions, 0 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f03c7ca44ba..3f6847be91b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2871,6 +2871,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) } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index b8bf2b69120..4f3d1d45679 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -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) } diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed new file mode 100644 index 00000000000..bdb884f5431 --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.fixed @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let _ptr1: *const u32 = std::ptr::null(); + let _ptr2: *const u32 = std::ptr::null(); + let _a = _ptr1.wrapping_add(5); //~ ERROR cannot add + let _b = _ptr1.wrapping_sub(5); //~ ERROR cannot subtract + let _c = unsafe { _ptr2.offset_from(_ptr1) }; //~ ERROR cannot subtract + let _d = _ptr1.wrapping_add(5); //~ ERROR cannot index +} diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs new file mode 100644 index 00000000000..cf68850cc4d --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.rs @@ -0,0 +1,10 @@ +// run-rustfix + +fn main() { + let _ptr1: *const u32 = std::ptr::null(); + let _ptr2: *const u32 = std::ptr::null(); + let _a = _ptr1 + 5; //~ ERROR cannot add + let _b = _ptr1 - 5; //~ ERROR cannot subtract + let _c = _ptr2 - _ptr1; //~ ERROR cannot subtract + let _d = _ptr1[5]; //~ ERROR cannot index +} diff --git a/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr new file mode 100644 index 00000000000..c55930da225 --- /dev/null +++ b/tests/ui/typeck/issue-112252-ptr-arithmetics-help.stderr @@ -0,0 +1,54 @@ +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} + | +LL | let _a = _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 `wrapping_sub` or `sub` for pointer - {integer} + | +LL | let _b = _ptr1.wrapping_sub(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 + | +LL | let _c = unsafe { _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 + +Some errors have detailed explanations: E0369, E0608. +For more information about an error, try `rustc --explain E0369`. |
