Skip to content

Commit 6ebca3c

Browse files
committed
Add detection of [Partial]Ord methods to the ambiguous wide ptr cmp lint
1 parent 1b2e9e4 commit 6ebca3c

File tree

8 files changed

+248
-79
lines changed

8 files changed

+248
-79
lines changed

compiler/rustc_lint/src/lints.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1583,14 +1583,16 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
15831583
Cast {
15841584
deref_left: &'a str,
15851585
deref_right: &'a str,
1586-
#[suggestion_part(code = "{deref_left}")]
1586+
paren_left: &'a str,
1587+
paren_right: &'a str,
1588+
#[suggestion_part(code = "({deref_left}")]
15871589
left_before: Option<Span>,
1588-
#[suggestion_part(code = " as *const ()")]
1589-
left: Span,
1590-
#[suggestion_part(code = "{deref_right}")]
1590+
#[suggestion_part(code = "{paren_left}.cast::<()>()")]
1591+
left_after: Span,
1592+
#[suggestion_part(code = "({deref_right}")]
15911593
right_before: Option<Span>,
1592-
#[suggestion_part(code = " as *const ()")]
1593-
right: Span,
1594+
#[suggestion_part(code = "{paren_right}.cast::<()>()")]
1595+
right_after: Span,
15941596
},
15951597
}
15961598

compiler/rustc_lint/src/types.rs

+26-20
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ fn lint_nan<'tcx>(
657657
fn lint_wide_pointer<'tcx>(
658658
cx: &LateContext<'tcx>,
659659
e: &'tcx hir::Expr<'tcx>,
660-
binop: hir::BinOpKind,
660+
binop: Option<hir::BinOpKind>,
661661
l: &'tcx hir::Expr<'tcx>,
662662
r: &'tcx hir::Expr<'tcx>,
663663
) {
@@ -676,7 +676,7 @@ fn lint_wide_pointer<'tcx>(
676676
}
677677
};
678678

679-
// PartialEq::{eq,ne} takes references, remove any explicit references
679+
// the left and right operands can have references, remove any explicit references
680680
let l = l.peel_borrows();
681681
let r = r.peel_borrows();
682682

@@ -704,8 +704,8 @@ fn lint_wide_pointer<'tcx>(
704704
);
705705
};
706706

707-
let ne = if binop == hir::BinOpKind::Ne { "!" } else { "" };
708-
let is_eq_ne = matches!(binop, hir::BinOpKind::Eq | hir::BinOpKind::Ne);
707+
let ne = if binop == Some(hir::BinOpKind::Ne) { "!" } else { "" };
708+
let is_eq_ne = matches!(binop, Some(hir::BinOpKind::Eq | hir::BinOpKind::Ne));
709709
let is_dyn_comparison = l_inner_ty_is_dyn && r_inner_ty_is_dyn;
710710

711711
let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo());
@@ -742,12 +742,12 @@ fn lint_wide_pointer<'tcx>(
742742
AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
743743
deref_left,
744744
deref_right,
745-
// those two Options are required for correctness as having
746-
// an empty span and an empty suggestion is not permitted
747-
left_before: (l_ty_refs != 0).then_some(left),
748-
right_before: (r_ty_refs != 0).then(|| r_span.shrink_to_lo()),
749-
left: l_span.shrink_to_hi(),
750-
right,
745+
paren_left: (l_ty_refs != 0).then_some(")").unwrap_or_default(),
746+
paren_right: (r_ty_refs != 0).then_some(")").unwrap_or_default(),
747+
left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),
748+
left_after: l_span.shrink_to_hi(),
749+
right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()),
750+
right_after: r_span.shrink_to_hi(),
751751
}
752752
},
753753
},
@@ -770,7 +770,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
770770
cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
771771
} else {
772772
lint_nan(cx, e, binop, l, r);
773-
lint_wide_pointer(cx, e, binop.node, l, r);
773+
lint_wide_pointer(cx, e, Some(binop.node), l, r);
774774
}
775775
}
776776
}
@@ -779,14 +779,14 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
779779
if let ExprKind::Path(ref qpath) = path.kind
780780
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
781781
&& let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
782-
&& let Some(binop) = partialeq_binop(diag_item) =>
782+
&& let Some(binop) = diag_item_binop(diag_item) =>
783783
{
784784
lint_wide_pointer(cx, e, binop, l, r);
785785
}
786786
hir::ExprKind::MethodCall(_, l, [r], _)
787787
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
788788
&& let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
789-
&& let Some(binop) = partialeq_binop(diag_item) =>
789+
&& let Some(binop) = diag_item_binop(diag_item) =>
790790
{
791791
lint_wide_pointer(cx, e, binop, l, r);
792792
}
@@ -873,13 +873,19 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
873873
)
874874
}
875875

876-
fn partialeq_binop(diag_item: Symbol) -> Option<hir::BinOpKind> {
877-
if diag_item == sym::cmp_partialeq_eq {
878-
Some(hir::BinOpKind::Eq)
879-
} else if diag_item == sym::cmp_partialeq_ne {
880-
Some(hir::BinOpKind::Ne)
881-
} else {
882-
None
876+
fn diag_item_binop(diag_item: Symbol) -> Option<Option<hir::BinOpKind>> {
877+
match diag_item {
878+
sym::cmp_ord_max => Some(None),
879+
sym::cmp_ord_min => Some(None),
880+
sym::ord_cmp_method => Some(None),
881+
sym::cmp_partialeq_eq => Some(Some(hir::BinOpKind::Eq)),
882+
sym::cmp_partialeq_ne => Some(Some(hir::BinOpKind::Ne)),
883+
sym::cmp_partialord_cmp => Some(None),
884+
sym::cmp_partialord_ge => Some(Some(hir::BinOpKind::Ge)),
885+
sym::cmp_partialord_gt => Some(Some(hir::BinOpKind::Gt)),
886+
sym::cmp_partialord_le => Some(Some(hir::BinOpKind::Le)),
887+
sym::cmp_partialord_lt => Some(Some(hir::BinOpKind::Lt)),
888+
_ => None,
883889
}
884890
}
885891
}

library/core/src/ptr/const_ptr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,7 @@ impl<T: ?Sized> Ord for *const T {
18021802
#[stable(feature = "rust1", since = "1.0.0")]
18031803
impl<T: ?Sized> PartialOrd for *const T {
18041804
#[inline]
1805+
#[allow(ambiguous_wide_pointer_comparisons)]
18051806
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
18061807
Some(self.cmp(other))
18071808
}

library/core/src/ptr/metadata.rs

+1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {
258258

259259
impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
260260
#[inline]
261+
#[allow(ambiguous_wide_pointer_comparisons)]
261262
fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
262263
(self.vtable_ptr as *const VTable).cmp(&(other.vtable_ptr as *const VTable))
263264
}

library/core/src/ptr/mut_ptr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,7 @@ impl<T: ?Sized> Ord for *mut T {
22262226
#[stable(feature = "rust1", since = "1.0.0")]
22272227
impl<T: ?Sized> PartialOrd for *mut T {
22282228
#[inline(always)]
2229+
#[allow(ambiguous_wide_pointer_comparisons)]
22292230
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
22302231
Some(self.cmp(other))
22312232
}

library/core/src/ptr/non_null.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,7 @@ impl<T: ?Sized> PartialEq for NonNull<T> {
18021802
#[stable(feature = "nonnull", since = "1.25.0")]
18031803
impl<T: ?Sized> Ord for NonNull<T> {
18041804
#[inline]
1805+
#[allow(ambiguous_wide_pointer_comparisons)]
18051806
fn cmp(&self, other: &Self) -> Ordering {
18061807
self.as_ptr().cmp(&other.as_ptr())
18071808
}
@@ -1810,6 +1811,7 @@ impl<T: ?Sized> Ord for NonNull<T> {
18101811
#[stable(feature = "nonnull", since = "1.25.0")]
18111812
impl<T: ?Sized> PartialOrd for NonNull<T> {
18121813
#[inline]
1814+
#[allow(ambiguous_wide_pointer_comparisons)]
18131815
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
18141816
self.as_ptr().partial_cmp(&other.as_ptr())
18151817
}

tests/ui/lint/wide_pointer_comparisons.rs

+24
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ fn main() {
3737
//~^ WARN ambiguous wide pointer comparison
3838
let _ = a.ne(&b);
3939
//~^ WARN ambiguous wide pointer comparison
40+
let _ = a.cmp(&b);
41+
//~^ WARN ambiguous wide pointer comparison
42+
let _ = a.partial_cmp(&b);
43+
//~^ WARN ambiguous wide pointer comparison
44+
let _ = a.le(&b);
45+
//~^ WARN ambiguous wide pointer comparison
46+
let _ = a.lt(&b);
47+
//~^ WARN ambiguous wide pointer comparison
48+
let _ = a.ge(&b);
49+
//~^ WARN ambiguous wide pointer comparison
50+
let _ = a.gt(&b);
51+
//~^ WARN ambiguous wide pointer comparison
4052

4153
{
4254
// &*const ?Sized
@@ -68,6 +80,18 @@ fn main() {
6880
//~^ WARN ambiguous wide pointer comparison
6981
let _ = a.ne(b);
7082
//~^ WARN ambiguous wide pointer comparison
83+
let _ = a.cmp(&b);
84+
//~^ WARN ambiguous wide pointer comparison
85+
let _ = a.partial_cmp(&b);
86+
//~^ WARN ambiguous wide pointer comparison
87+
let _ = a.le(&b);
88+
//~^ WARN ambiguous wide pointer comparison
89+
let _ = a.lt(&b);
90+
//~^ WARN ambiguous wide pointer comparison
91+
let _ = a.ge(&b);
92+
//~^ WARN ambiguous wide pointer comparison
93+
let _ = a.gt(&b);
94+
//~^ WARN ambiguous wide pointer comparison
7195
}
7296

7397
let s = "" as *const str;

0 commit comments

Comments
 (0)