-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Implement raw fat pointer comparisons #1135
Conversation
type like a fat raw pointer should implement equality in some way. | ||
|
||
However, there doesn't seem to be a sensible way to order raw fat pointers | ||
unless we take vtable addresses into account, which is relatively weird. |
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.
PartialOrd
makes much more sense for raw slices *const [T]
than for trait pointers, and the ordering is quite clear - (begin1, len1) < (begin2, len2).
(Speaking of weirdness, ordering for unrelated thin pointers doesn't make much sense too (C++, for example, doesn't even define it), but it exists just because having some ordering is useful.)
It would be good to either make it more obvious this is specific to fat pointers, or explain that equality and ordering already exist for thin pointers (of the same type at least). The way it's current written made me think that you were suggesting removing ordering from all raw pointers. |
raw pointers and all fat raw pointers. I don't like this because equality | ||
between fat raw pointers of different traits is false most of the | ||
time (unless one of the traits is a supertrait of the other and/or the | ||
only difference is in free lifetimes), and anyway you can always compare |
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.
Depending on your version of equality there are other ways this can be true. If you ignore the vtables, and only compare the pointers (which is how I would define fat-ptr equality) then you can have two fat pointers of unrelated types which are equal:
let x = &T;
let a: &Tr1 = x;
let b: &Tr2 = x;
a == b
As long as T
implements both Tr1
and Tr2
, then the two traits do not have to be related in any way.
We haven't yet implemented casting from &Tr1
to &Tr1 + Tr2
, so any cast would have to be to *u8
or something.
I think there is a deep question here which is, should we be able to compare pointers which point to different types. If we think yes, then we should allow heterogeneous fat ptr comparison. If not, then we should not allow any fat ptr comparison, since the 'real' type of a fat pointer is not known, so we might be comparing pointers to different types. I think the answer should be 'yes' for raw pointers, I don't see much of a downside. These are comparisons of the pointer, not the value pointed to, so they are clearly comparable things. I think we can afford to be a little less 'safe' here since we are only talking about raw pointers. I can imagine we might not allow any comparison (since we don't allow arithmetic) but if we are going to allow comparison I don't see why there should be a type restriction. The other point is whether we should involve the vtables (or array lengths) in the comparison. I think we should not do this. The organisation of the vtable is an implementation detail that we may change, so it should not be exposed in any way to the programmer. |
I think you would have to include the vtable pointer in the comparison. For trait objects pointing to zero-sized types, the address of the fat pointer might be a sentinel (depending on allocator behavior). |
Similarly, a struct and the first field in a struct could implement the same trait. Thus, the address could be the same, but the vtable would vary. (which I now see is explicitly mentioned in the RFC) |
What would be the defined semantics for this with zero-sized types? (I don't like implicitly-supported pointer comparisons in general, since they make difficult a potential future optimization to represent |
@comex |
@comex well, |
I had thought that we should look only at the pointers for all kinds of comparison, but looking at the vtables too also seems a reasonable approach. In particular if two pointers have different vtables they would be not equal and could not be compared for ordering. I don't have a strong preference for either kind of comparison; including the vtables seems marginally superior. |
Another related thing is that for some HPC use cases, pointer equality is often a useful property. |
This would be extremely useful. I'm very much in favor. |
Hear ye, hear ye. This RFC is now entering final comment period. |
@arielb1 there's a few comments in the thread about whether to include the vtable info in the comparison, to you have an opinion beyond what is in the RFC? I just wanted to check you didn't have more thoughts here, otherwise we (lang team) think this is ready to merge. |
that's it, merge the RFC as is (comparing vtable addresses), and prohibit |
I definitely think vtables should be part of the comparison. Two examples:
(We discussed this in the lang team meeting, these points were raised there.) |
That was my initial thought too. What should happen with |
Yes, I think the current system is just a poor man's obligation. I personally have no problem supporting |
[bikeshed] is the vtable or addr more significant? |
@arielb1 whichever comes first in our current representation :) |
Huzzah! The language design subteam has decided to accept this RFC. The canonical text is now in the repository and the tracking issue for implementation is at rust-lang/rust#28236. Note: there is still an unresolved question, perhaps suitable for a followup RFC or amendment, about ordering beyond equality. |
Rendered