about summary refs log tree commit diff
path: root/compiler/rustc_lint/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-29 18:23:57 +0000
committerbors <bors@rust-lang.org>2024-03-29 18:23:57 +0000
commitaf4a5a13a15fa0c60e06321077ef452f769b42fd (patch)
tree34fa2676e47438840fbdb8ced2dbf3337452935d /compiler/rustc_lint/src
parent399fa2f6e419fd2c70942c191c2e55814af8d167 (diff)
parentd4b514f982e4214e0f9237c905670b1207ae0c95 (diff)
downloadrust-af4a5a13a15fa0c60e06321077ef452f769b42fd.tar.gz
rust-af4a5a13a15fa0c60e06321077ef452f769b42fd.zip
Auto merge of #121268 - Urgau:improve_ambi_wide_ptr_cmps, r=Nadrieril
Add detection of [Partial]Ord methods in the `ambiguous_wide_pointer_comparisons` lint

Partially addresses https://github.com/rust-lang/rust/issues/121264 by adding diagnostics items for PartialOrd and Ord methods, detecting such diagnostics items as "binary operation" and suggesting the correct replacement.

I also took the opportunity to change the suggestion to use new methods `.cast()` on `*mut T` an d `*const T`.
Diffstat (limited to 'compiler/rustc_lint/src')
-rw-r--r--compiler/rustc_lint/src/lints.rs14
-rw-r--r--compiler/rustc_lint/src/types.rs58
2 files changed, 43 insertions, 29 deletions
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 1dac2d89c6b..cf3890dc61c 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1668,14 +1668,16 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
     Cast {
         deref_left: &'a str,
         deref_right: &'a str,
-        #[suggestion_part(code = "{deref_left}")]
+        paren_left: &'a str,
+        paren_right: &'a str,
+        #[suggestion_part(code = "({deref_left}")]
         left_before: Option<Span>,
-        #[suggestion_part(code = " as *const ()")]
-        left: Span,
-        #[suggestion_part(code = "{deref_right}")]
+        #[suggestion_part(code = "{paren_left}.cast::<()>()")]
+        left_after: Span,
+        #[suggestion_part(code = "({deref_right}")]
         right_before: Option<Span>,
-        #[suggestion_part(code = " as *const ()")]
-        right: Span,
+        #[suggestion_part(code = "{paren_right}.cast::<()>()")]
+        right_after: Span,
     },
 }
 
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 5331d2fb752..68cc024d9c7 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -657,10 +657,16 @@ fn lint_nan<'tcx>(
     cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint);
 }
 
+#[derive(Debug, PartialEq)]
+enum ComparisonOp {
+    BinOp(hir::BinOpKind),
+    Other,
+}
+
 fn lint_wide_pointer<'tcx>(
     cx: &LateContext<'tcx>,
     e: &'tcx hir::Expr<'tcx>,
-    binop: hir::BinOpKind,
+    cmpop: ComparisonOp,
     l: &'tcx hir::Expr<'tcx>,
     r: &'tcx hir::Expr<'tcx>,
 ) {
@@ -679,7 +685,7 @@ fn lint_wide_pointer<'tcx>(
         }
     };
 
-    // PartialEq::{eq,ne} takes references, remove any explicit references
+    // the left and right operands can have references, remove any explicit references
     let l = l.peel_borrows();
     let r = r.peel_borrows();
 
@@ -707,8 +713,8 @@ fn lint_wide_pointer<'tcx>(
         );
     };
 
-    let ne = if binop == hir::BinOpKind::Ne { "!" } else { "" };
-    let is_eq_ne = matches!(binop, hir::BinOpKind::Eq | hir::BinOpKind::Ne);
+    let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" };
+    let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne));
     let is_dyn_comparison = l_inner_ty_is_dyn && r_inner_ty_is_dyn;
 
     let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo());
@@ -745,12 +751,12 @@ fn lint_wide_pointer<'tcx>(
                 AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
                     deref_left,
                     deref_right,
-                    // those two Options are required for correctness as having
-                    // an empty span and an empty suggestion is not permitted
-                    left_before: (l_ty_refs != 0).then_some(left),
-                    right_before: (r_ty_refs != 0).then(|| r_span.shrink_to_lo()),
-                    left: l_span.shrink_to_hi(),
-                    right,
+                    paren_left: if l_ty_refs != 0 { ")" } else { "" },
+                    paren_right: if r_ty_refs != 0 { ")" } else { "" },
+                    left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),
+                    left_after: l_span.shrink_to_hi(),
+                    right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()),
+                    right_after: r_span.shrink_to_hi(),
                 }
             },
         },
@@ -773,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
                         cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
                     } else {
                         lint_nan(cx, e, binop, l, r);
-                        lint_wide_pointer(cx, e, binop.node, l, r);
+                        lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r);
                     }
                 }
             }
@@ -782,16 +788,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
                 if let ExprKind::Path(ref qpath) = path.kind
                     && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
                     && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
-                    && let Some(binop) = partialeq_binop(diag_item) =>
+                    && let Some(cmpop) = diag_item_cmpop(diag_item) =>
             {
-                lint_wide_pointer(cx, e, binop, l, r);
+                lint_wide_pointer(cx, e, cmpop, l, r);
             }
             hir::ExprKind::MethodCall(_, l, [r], _)
                 if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
                     && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
-                    && let Some(binop) = partialeq_binop(diag_item) =>
+                    && let Some(cmpop) = diag_item_cmpop(diag_item) =>
             {
-                lint_wide_pointer(cx, e, binop, l, r);
+                lint_wide_pointer(cx, e, cmpop, l, r);
             }
             _ => {}
         };
@@ -876,14 +882,20 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
             )
         }
 
-        fn partialeq_binop(diag_item: Symbol) -> Option<hir::BinOpKind> {
-            if diag_item == sym::cmp_partialeq_eq {
-                Some(hir::BinOpKind::Eq)
-            } else if diag_item == sym::cmp_partialeq_ne {
-                Some(hir::BinOpKind::Ne)
-            } else {
-                None
-            }
+        fn diag_item_cmpop(diag_item: Symbol) -> Option<ComparisonOp> {
+            Some(match diag_item {
+                sym::cmp_ord_max => ComparisonOp::Other,
+                sym::cmp_ord_min => ComparisonOp::Other,
+                sym::ord_cmp_method => ComparisonOp::Other,
+                sym::cmp_partialeq_eq => ComparisonOp::BinOp(hir::BinOpKind::Eq),
+                sym::cmp_partialeq_ne => ComparisonOp::BinOp(hir::BinOpKind::Ne),
+                sym::cmp_partialord_cmp => ComparisonOp::Other,
+                sym::cmp_partialord_ge => ComparisonOp::BinOp(hir::BinOpKind::Ge),
+                sym::cmp_partialord_gt => ComparisonOp::BinOp(hir::BinOpKind::Gt),
+                sym::cmp_partialord_le => ComparisonOp::BinOp(hir::BinOpKind::Le),
+                sym::cmp_partialord_lt => ComparisonOp::BinOp(hir::BinOpKind::Lt),
+                _ => return None,
+            })
         }
     }
 }