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

Make #[derive(Copy, Eq, Ord)] imply #[derive(Clone, PartialEq, PartialOrd)] #23905

Closed
wants to merge 9 commits into from

Conversation

Projects
None yet
9 participants
@erickt
Copy link
Contributor

erickt commented Mar 31, 2015

This reduces the amount of boilerplate users need to do in order to derive some common traits.

This is related to #23860.

cc @nikomatsakis, @aturon

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Mar 31, 2015

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
trait_def.expand(cx, mitem, item, push);

partial_ord::expand_deriving_partial_ord(cx, span, mitem, item, push)

This comment has been minimized.

@sfackler

sfackler Mar 31, 2015

Member

The derived partial_cmp can be optimized in this case to just Some(self.cmp(other)).

EDIT: Hmm, though they're not totally equivalent in the presence of type paramters unfortunately.

This comment has been minimized.

@erickt

erickt Mar 31, 2015

Author Contributor

Good point. I've got a build running that applies this PartialOrd optimization to non-generic types. I'll push it up when it finishes running.

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Mar 31, 2015

🎯

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Mar 31, 2015

Out of curiosity, is it still possible to have #[derive(Ord)] but a manual implementation of PartialOrd?

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Mar 31, 2015

@alexcrichton I think the more common thing would be the opposite since PartialOrd has a trivial impl if you've already implemented Ord::cmp.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Mar 31, 2015

Hm true. In general I've been very worried in the past about this form of deriving as it seems like a footgun for various forms of configuration of deriving. For example it looks like instances of derive(Eq) with a manual PartialEq impl were removed in favor of a manual Eq impl. I worry about the "half-derive" case, but it may not be too large of a worry in practice. For example adding an impl of Eq is just a marker trait so it's not so bad, and I'm not sure how much this applies to Ord and PartialOrd...

@erickt

This comment has been minimized.

Copy link
Contributor Author

erickt commented Apr 1, 2015

@alexcrichton: with this PR we could no longer provide a manual implementation of PartialOrd with #[derive(Ord)]. Is there ever a case where we'd want a manual implementation if we already have version of Ord? That also seems like it could be a source of bugs if the two were inconsistent.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 1, 2015

My main concern is whether this PR requires an RFC. It seems to be at least mildly controversial. Obviously this would have to land by 1.0 though! (I personally acknowledge @alexcrichton's concerns, but think that this PR is a net improvement on the current situation.)

@erickt

This comment has been minimized.

Copy link
Contributor Author

erickt commented Apr 1, 2015

@sfackler: I just pushed up a patch that simplifies generating PartialOrd for non-generic Ord types. I'm not sure if my metrics are right, but this PR appears to be shaving off about 100KB from libstd.dylib when compared with the latest nightly libstd.dylib, but I can't say if that's all due to this PR or some other optimizations going on. I could do a fresh build to compare the too if we want a real number.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 1, 2015

r+ from me (modulo RFC) but I'm not really that familiar with this code. Certainly I'd like to hear @sfackler or @huonw weigh in.

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Apr 2, 2015

☔️ The latest upstream changes (presumably #23963) made this pull request unmergeable. Please resolve the merge conflicts.

@erickt erickt force-pushed the erickt:copy branch from bdf418d to a14f3a5 Apr 2, 2015

@erickt

This comment has been minimized.

Copy link
Contributor Author

erickt commented Apr 2, 2015

I rebased on top of HEAD to avoid some merge conflicts and squashed some of the cleanup commits together.

erickt added some commits Mar 27, 2015

syntax: Change deriving methods to take a `&mut FnMut(P<Item>)`
This allows #[derive(...)]` to create more than one impl
syntax: Shrink the impl PartialOrd with #[derive(Ord)]
This PR generates a simplified `PartialOrd` implementation when the
type is `Ord` and non-generic. It produces essentially:

impl ::std::cmp::PartialOrd for $ty {
    fn partial_cmp(&self, other: &$ty) -> Option<std::cmp::Ordering> {
        Some(::std::cmp::Ord::cmp(self, other))
    }
}
@huonw

This comment has been minimized.

Copy link

huonw commented on src/libsyntax/ext/deriving/cmp/ord.rs in eed443b Apr 3, 2015

Missing Some?

This comment has been minimized.

Copy link
Owner Author

erickt replied Apr 3, 2015

Good catch!

@huonw

This comment has been minimized.

Copy link

huonw commented on src/libsyntax/ext/deriving/cmp/ord.rs in eed443b Apr 3, 2015

I believe it should be able to made work via the self_args fields of Substructure.

@huonw

This comment has been minimized.

Copy link
Member

huonw commented Apr 3, 2015

Copying this comment to ensure it doesn't get lost: I believe it one should be able to make the simple-impls work via the self_args fields of Substructure.

Also, another minor point: what about supporting #[derive(Copy, Clone)] struct Foo; (i.e. explicitly write the Clone?)?

Alsoalso, I wonder about the case of optimising PartialOrd (e.g. maybe < can be computed faster than a full comparison). There's a big cliff between:

#[derive(Ord)]
struct Foo { ... }

and

struct Foo { ... }

impl Ord for Foo {
    fn cmp(&self, other: &Foo) -> Ordering {
        // ... lots of stuff ...
    }
}
impl PartialOrd for Foo {
     fn partial_cmp(&self, other: &Foo) -> Option<Ordering> { Some(self.cmp(other)) }
     fn lt(&self, other: &Foo) -> bool { /* supafast */ }
}

That said, it seems like this PR is the right default, and we can add an opt-out mechanism in future.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 3, 2015

Also, another minor point: what about supporting #[derive(Copy, Clone)] struct Foo; (i.e. explicitly write the Clone?)?

I thought the PR did permit this, albeit with a FIXME attached? (I tend to think we should just allow it and, at most, lint for it)

@erickt

This comment has been minimized.

Copy link
Contributor Author

erickt commented Apr 3, 2015

@nikomatsakis: Yes, this PR explicitly handles #[derive(Copy, Clone)]. A lint sounds fine to me.

bors added a commit that referenced this pull request Apr 6, 2015

Auto merge of #23985 - erickt:derive-cleanup, r=huonw
This extracts some of the minor cleanup patches from #23905.
@huonw

This comment has been minimized.

Copy link
Member

huonw commented Apr 6, 2015

Oh, I wasn't clear: my reading of the PR was that the support for that was only for staging reasons. In any case, a lint (or nothing) sounds good to me.

@dcrewi

This comment has been minimized.

Copy link
Contributor

dcrewi commented Apr 13, 2015

This should probably be closed now, as the RFC has been resolved?

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Apr 13, 2015

Yes thanks for the reminder @dcrewi! Closing for the same reasons as listed in the RFC.

bors added a commit that referenced this pull request Apr 18, 2015

Auto merge of #23985 - erickt:derive-cleanup, r=erickt
This extracts some of the minor cleanup patches from #23905.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.