Skip to content

Commit ef49365

Browse files
committed
Auto merge of #123207 - Urgau:improve_ambi_non_null, r=Nadrieril
Add support for `NonNull`s in the `ambiguous_wide_ptr_comparisions` lint This PR add support for `NonNull` pointers in the `ambiguous_wide_ptr_comparisions` lint. Fixes #121264 r? `@Nadrieril` (since you just reviewed #121268, feel free to reassign)
2 parents 1852728 + 16d11c5 commit ef49365

File tree

5 files changed

+139
-65
lines changed

5 files changed

+139
-65
lines changed

compiler/rustc_data_structures/src/tagged_ptr/copy.rs

+1
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ where
243243
T: Tag,
244244
{
245245
#[inline]
246+
#[allow(ambiguous_wide_pointer_comparisons)]
246247
fn eq(&self, other: &Self) -> bool {
247248
self.packed == other.packed
248249
}

compiler/rustc_lint/src/lints.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -1632,11 +1632,13 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
16321632
pub ne: &'a str,
16331633
pub deref_left: &'a str,
16341634
pub deref_right: &'a str,
1635+
pub l_modifiers: &'a str,
1636+
pub r_modifiers: &'a str,
16351637
#[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
16361638
pub left: Span,
1637-
#[suggestion_part(code = ", {deref_right}")]
1639+
#[suggestion_part(code = "{l_modifiers}, {deref_right}")]
16381640
pub middle: Span,
1639-
#[suggestion_part(code = ")")]
1641+
#[suggestion_part(code = "{r_modifiers})")]
16401642
pub right: Span,
16411643
}
16421644

@@ -1652,11 +1654,13 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
16521654
ne: &'a str,
16531655
deref_left: &'a str,
16541656
deref_right: &'a str,
1657+
l_modifiers: &'a str,
1658+
r_modifiers: &'a str,
16551659
#[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
16561660
left: Span,
1657-
#[suggestion_part(code = ", {deref_right}")]
1661+
#[suggestion_part(code = "{l_modifiers}, {deref_right}")]
16581662
middle: Span,
1659-
#[suggestion_part(code = ")")]
1663+
#[suggestion_part(code = "{r_modifiers})")]
16601664
right: Span,
16611665
},
16621666
#[multipart_suggestion(
@@ -1670,13 +1674,15 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
16701674
deref_right: &'a str,
16711675
paren_left: &'a str,
16721676
paren_right: &'a str,
1677+
l_modifiers: &'a str,
1678+
r_modifiers: &'a str,
16731679
#[suggestion_part(code = "({deref_left}")]
16741680
left_before: Option<Span>,
1675-
#[suggestion_part(code = "{paren_left}.cast::<()>()")]
1681+
#[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
16761682
left_after: Span,
16771683
#[suggestion_part(code = "({deref_right}")]
16781684
right_before: Option<Span>,
1679-
#[suggestion_part(code = "{paren_right}.cast::<()>()")]
1685+
#[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
16801686
right_after: Span,
16811687
},
16821688
}

compiler/rustc_lint/src/types.rs

+30-8
Original file line numberDiff line numberDiff line change
@@ -670,19 +670,32 @@ fn lint_wide_pointer<'tcx>(
670670
l: &'tcx hir::Expr<'tcx>,
671671
r: &'tcx hir::Expr<'tcx>,
672672
) {
673-
let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(usize, bool)> {
673+
let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(
674+
/* number of refs */ usize,
675+
/* modifiers */ String,
676+
/* is dyn */ bool,
677+
)> {
674678
let mut refs = 0;
675679
// here we remove any "implicit" references and count the number
676680
// of them to correctly suggest the right number of deref
677681
while let ty::Ref(_, inner_ty, _) = ty.kind() {
678682
ty = *inner_ty;
679683
refs += 1;
680684
}
681-
match ty.kind() {
682-
ty::RawPtr(ty, _) => (!ty.is_sized(cx.tcx, cx.param_env))
683-
.then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn)))),
684-
_ => None,
685-
}
685+
686+
// get the inner type of a pointer (or akin)
687+
let mut modifiers = String::new();
688+
ty = match ty.kind() {
689+
ty::RawPtr(ty, _) => *ty,
690+
ty::Adt(def, args) if cx.tcx.is_diagnostic_item(sym::NonNull, def.did()) => {
691+
modifiers.push_str(".as_ptr()");
692+
args.type_at(0)
693+
}
694+
_ => return None,
695+
};
696+
697+
(!ty.is_sized(cx.tcx, cx.param_env))
698+
.then(|| (refs, modifiers, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn))))
686699
};
687700

688701
// the left and right operands can have references, remove any explicit references
@@ -696,10 +709,10 @@ fn lint_wide_pointer<'tcx>(
696709
return;
697710
};
698711

699-
let Some((l_ty_refs, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
712+
let Some((l_ty_refs, l_modifiers, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
700713
return;
701714
};
702-
let Some((r_ty_refs, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
715+
let Some((r_ty_refs, r_modifiers, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
703716
return;
704717
};
705718

@@ -724,6 +737,9 @@ fn lint_wide_pointer<'tcx>(
724737
let deref_left = &*"*".repeat(l_ty_refs);
725738
let deref_right = &*"*".repeat(r_ty_refs);
726739

740+
let l_modifiers = &*l_modifiers;
741+
let r_modifiers = &*r_modifiers;
742+
727743
cx.emit_span_lint(
728744
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
729745
e.span,
@@ -733,6 +749,8 @@ fn lint_wide_pointer<'tcx>(
733749
ne,
734750
deref_left,
735751
deref_right,
752+
l_modifiers,
753+
r_modifiers,
736754
left,
737755
middle,
738756
right,
@@ -743,6 +761,8 @@ fn lint_wide_pointer<'tcx>(
743761
ne,
744762
deref_left,
745763
deref_right,
764+
l_modifiers,
765+
r_modifiers,
746766
left,
747767
middle,
748768
right,
@@ -751,6 +771,8 @@ fn lint_wide_pointer<'tcx>(
751771
AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
752772
deref_left,
753773
deref_right,
774+
l_modifiers,
775+
r_modifiers,
754776
paren_left: if l_ty_refs != 0 { ")" } else { "" },
755777
paren_right: if r_ty_refs != 0 { ")" } else { "" },
756778
left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),

tests/ui/lint/wide_pointer_comparisons.rs

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::rc::Rc;
44
use std::sync::Arc;
55
use std::cmp::PartialEq;
6+
use std::ptr::NonNull;
67

78
struct A;
89
struct B;
@@ -50,6 +51,17 @@ fn main() {
5051
let _ = a.gt(&b);
5152
//~^ WARN ambiguous wide pointer comparison
5253

54+
{
55+
let a = NonNull::<dyn T>::new(a as *mut _).unwrap();
56+
let b = NonNull::<dyn T>::new(b as *mut _).unwrap();
57+
let _ = a == b;
58+
//~^ WARN ambiguous wide pointer comparison
59+
let _ = a >= b;
60+
//~^ WARN ambiguous wide pointer comparison
61+
let _ = &a == &b;
62+
//~^ WARN ambiguous wide pointer comparison
63+
}
64+
5365
{
5466
// &*const ?Sized
5567
let a = &a;

0 commit comments

Comments
 (0)