-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
RFC: Change operator method lookup to be less magical #4920
Comments
I think this should apply also to unary operators and the |
Discussed in meeting: https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-03-12 |
It seems that we only partially discussed this issue in the meeting. In particular, we did not discuss:
On point 2, currently |
seems reasonable to me |
Looks like this was merged in #5558 .. @nikomatsakis can this close? |
Visiting for triage, email from 2013-09-02. Nominating for milestone 1, well-defined. (Of course, its possible that graydon's hypothesis that this might be closeable is true. @nikomatsakis, any thoughts?) |
Not closeable in that point 1 remains unresolved: do we want to coerce arguments? I remember @pcwalton had this on the agenda recently (under the guise of |
Accepted for milestone 1, well-defined |
Triage bump, this still needs some work. |
Should this go through the new RFC process? I hope that |
This issue has been moved to the RFCs repo: rust-lang/rfcs#283 |
@nick29581 I think @rust-highfive shouldn't have closed this issue, since it's marked as P-backcompat-lang - unless that tag no longer applies, but I don't think that's the case here. |
reopening and nominating for triage to decide what to do with this |
Repeating a relevant comment from #16918: what I'm most concerned about is that, currently, we do a kind of odd-ball search when looking up operators. e.g., if we have l + r, where the types of l and r are L and R, I just want to search for Add<L,R>, rather than doing a traditional method search (which involves auto-ref, coercion, and other considerations). This does mean that in some cases we might wind up writing "convenience" impls for things like String compared with &str that basically encode common coercions. But I think it's more predictable overall. Today I whippe up a prototype of this approach, though it doesn't quite build yet. One obstacle is the current Eq and Ord traits which do not permit comparison between two distinct types for some reason. |
I am working on this. I consider this a bug fix and not RFC worthy, though this is perhaps debatable. Basically what I am implementing is what I think the semantics were supposed to be, and it requires very few changes to existing code anyhow since most code is using operators as intended. Basically the changes I am doing are:
Point 2 is what occasionally causes breakage. We used to accept things like Now, I think there are changes we could (and should) make to the operator traits themselves (as I have discussed with @aturon), but what I'm working on now is strictly limited to how the operator traits are matched in the compiler. |
This branch cleans up overloaded operator resolution so that it is strictly based on the traits in `ops`, rather than going through the normal method lookup mechanism. It also adds full support for autoderef to overloaded index (whereas before autoderef only worked for non-overloaded index) as well as for the slicing operators. This is a [breaking-change]: in the past, we were accepting combinations of operands that were not intended to be accepted. For example, it was possible to compare a fixed-length array and a slice, or apply the `!` operator to a `&int`. See the first two commits in this pull-request for examples. One downside of this change is that comparing fixed-length arrays doesn't always work as smoothly as it did before. Before this, comparisons sometimes worked due to various coercions to slices. I've added impls for `Eq`, `Ord`, etc for fixed-lengths arrays up to and including length 32, but if the array is longer than that you'll need to either newtype the array or convert to slices. Note that this plays better with deriving in any case than the previous scheme. Fixes #4920. Fixes #16821. Fixes #15757. cc @alexcrichton cc @aturon
Right now, operator "methods" proceed according to the same logic as any other method. But this leads to surprising results like this: https://gist.github.com/bstrie/4948410
Also, operators are already handled somewhat specially because we auto-ref their arguments. This means that you can write
val1-of-my-linear-type == val2-of-my-linear-type
and it doesn't move or do anything creepy (to call eq explicitly, in contrast, you'd writeval1-of-my-linear-type.eq(&val2-of-my-linear-type)
).I think method lookup for operators should never apply any automatic transformations to the receiver or arguments, other than the current auto-ref behavior (which means that
a OP b
is kind of implicitly(&a).OP(&b)
)@pcwalton I expect you in particular might have an opinion about this.
The text was updated successfully, but these errors were encountered: