-
Notifications
You must be signed in to change notification settings - Fork 13.8k
document that ptr cmp is unsigned #136364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
library/core/src/ptr/const_ptr.rs
Outdated
impl<T: ?Sized> Eq for *const T {} | ||
|
||
// Comparison for pointers | ||
/// Pointers are compared as if they are usize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Pointers are compared as if they are usize | |
/// Pointers are compared as an unsigned value with exposed provenance. |
I think mentioning the provenance story may be worthwhile here, because aiui otherwise comparing pointers with different provenance would be unsound. @RalfJung is this accurate?
Could you add the same docs to PartialEq
and PartialOrd
? *mut
should get similar changes
rust/library/core/src/ptr/mut_ptr.rs
Lines 2100 to 2129 in aa4cfd0
// Equality for pointers | |
#[stable(feature = "rust1", since = "1.0.0")] | |
impl<T: ?Sized> PartialEq for *mut T { | |
#[inline(always)] | |
#[allow(ambiguous_wide_pointer_comparisons)] | |
fn eq(&self, other: &*mut T) -> bool { | |
*self == *other | |
} | |
} | |
#[stable(feature = "rust1", since = "1.0.0")] | |
impl<T: ?Sized> Eq for *mut T {} | |
#[stable(feature = "rust1", since = "1.0.0")] | |
impl<T: ?Sized> Ord for *mut T { | |
#[inline] | |
#[allow(ambiguous_wide_pointer_comparisons)] | |
fn cmp(&self, other: &*mut T) -> Ordering { | |
if self < other { | |
Less | |
} else if self == other { | |
Equal | |
} else { | |
Greater | |
} | |
} | |
} | |
#[stable(feature = "rust1", since = "1.0.0")] | |
impl<T: ?Sized> PartialOrd for *mut T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provenance does not get exposed by comparison so the "with exposed provenance" part doesn't seem right. I don't even know what exactly it should mean though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think mentioning the provenance story may be worthwhile here, because aiui otherwise comparing pointers with different provenance would be unsound
why would this comparison be unsound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the easiest way to document this is to just say that pointers are compared by comparing the result of calling addr()
. That covers most everything relevant:
- Provenance does not get exposed
- Provenance does not influence the result
- The comparison happens at type
usize
, i.e., it is unsigned
It does not say what happens with wide pointers, but that is an orthogonal question anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provenance does not get exposed by comparison
I said the wrong thing here; I meant to say that provenance is taken into account, not that it is exposed (sorry, provenance lingo is all still all a bit new to me...).
why would this comparison be unsound?
AIUI any kind of comparison of pointers across allocations would ride the non-deterministic/unsound line if provenance matters, but this isn't a problem based on the above.
Ralf or Jubille if you want to yoink this review feel free, I'm happy to though if you have no preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tgross35 There's some nondeterminism always because, well, pointers are simply like that. Especially in const eval which can cause pointer comparisons to spuriously fail! That's why guaranteed_eq
exists. But nondet != unsound.
afaik it is of course strictly unsound in C and C++, but we're not C or c++
@bors r+ rollup |
Pointer comparison is fully deterministic in Rust. Pointer values are often chosen non-deterministically, but comparing the same two pointers will always produce the same result.
|
Fixes #77497