Skip to content
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

Merged
merged 1 commit into from
Sep 4, 2015

Conversation

arielb1
Copy link
Contributor

@arielb1 arielb1 commented May 27, 2015

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.
Copy link
Contributor

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.)

@nrc nrc self-assigned this May 27, 2015
@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label May 27, 2015
@Aatch
Copy link
Contributor

Aatch commented May 28, 2015

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
Copy link
Member

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.

@nrc nrc changed the title Implement raw pointer comparisons Implement raw fat pointer comparisons May 28, 2015
@nrc
Copy link
Member

nrc commented May 28, 2015

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.

@zkamsler
Copy link

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).

@zkamsler
Copy link

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)

@comex
Copy link

comex commented May 29, 2015

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 &T as T where T is pointer-sized or less...)

@zkamsler
Copy link

@comex
I would expect it to be the same as for non-zero sized types. There is still an address and a vtable/count. A raw pointer would be equal iff both are equal. The address is just less likely to be unique.

@nikomatsakis
Copy link
Contributor

@comex well, &T and *T are very different, right? In particular, this RFC does not describe &T comparisons. (unless I missed something)

@nrc
Copy link
Member

nrc commented Jun 3, 2015

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.

@llogiq
Copy link
Contributor

llogiq commented Jun 15, 2015

Another related thing is that for some HPC use cases, pointer equality is often a useful property.

@pythonesque
Copy link
Contributor

This would be extremely useful. I'm very much in favor.

@nikomatsakis nikomatsakis added the final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. label Jul 31, 2015
@nikomatsakis
Copy link
Contributor

Hear ye, hear ye. This RFC is now entering final comment period.

@nrc
Copy link
Member

nrc commented Aug 14, 2015

@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.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 16, 2015

@nrc

that's it, merge the RFC as is (comparing vtable addresses), and prohibit PartialOrd?

@nikomatsakis
Copy link
Contributor

I definitely think vtables should be part of the comparison. Two examples:

  1. A pointer to a struct and a pointer to its field field should not be equal. :)
  2. In general, if the vtable is unequal, it means some types are unequal, so even if it is the same memory, it must be being interpreted differently, or else a subset of that memory (as in case 1). The behavior will not be the same when you use the object, so why should it be equal? If you had static type information (a thin pointer), you couldn't even compare the two pointers, as you'd get a type error. So overall, doesn't make sense to me.

(We discussed this in the lang team meeting, these points were raised there.)

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 20, 2015

@nikomatsakis

That was my initial thought too. What should happen with PartialOrd through? I am afraid that banning it would weaken inference in the foo as *const _ < bar as *const _ case. Maybe casts should be obligations - that would fix it.

@nikomatsakis
Copy link
Contributor

@arielb1

casts should be obligations

Yes, I think the current system is just a poor man's obligation. I personally have no problem supporting PartialOrd -- it seems no more dubious than PartialOrd on other * pointers. You can hardly expect that to be stable across executions, but it's otherwise rather useful.

@arielb1
Copy link
Contributor Author

arielb1 commented Aug 24, 2015

@nikomatsakis

[bikeshed] is the vtable or addr more significant?

@nikomatsakis
Copy link
Contributor

@arielb1 whichever comes first in our current representation :)

@nikomatsakis
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-raw-pointers Proposals relating to raw pointers. final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants