about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-04 10:18:09 +0800
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-09 10:01:16 +0800
commit63d643da841bedd6b855f617edecc0b13c0cd71e (patch)
treedd76f9ba433420e012df2988e2c77836146f352d /compiler
parent8b35c0bb0f833c0077dc57006eb317edde2a2d1e (diff)
Add help for trying to do C-like pointer arithmetics
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs46
2 files changed, 61 insertions, 0 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3c5feb1ba51..5081285736e 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -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)
                 }
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)
             }