Skip to content

Ensure derive(PartialOrd) is no longer accidentally exponential #50011

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

Merged
merged 4 commits into from
May 15, 2018

Conversation

varkor
Copy link
Member

@varkor varkor commented Apr 16, 2018

Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once, addressing #49650 (comment).

Closes #49505.

r? @Manishearth (sorry for changing it again so soon!)

Close #50755

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 16, 2018
Copy link
Member

@Manishearth Manishearth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors r+

@Manishearth
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented Apr 16, 2018

📌 Commit 3ecaeba has been approved by Manishearth

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 16, 2018
@rust-lang rust-lang deleted a comment from rust-highfive Apr 17, 2018
@varkor
Copy link
Member Author

varkor commented Apr 17, 2018

Argh, messed up the default there, sorry.

@Manishearth
Copy link
Member

@bors r+

Please test this on various combinations of greater than/less than just in case 😄

@bors
Copy link
Collaborator

bors commented Apr 17, 2018

📌 Commit d0e6f70 has been approved by Manishearth

@rust-highfive
Copy link
Contributor

Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
Resolving deltas: 100% (616285/616285), completed with 4913 local objects.
---
[00:00:43] configure: rust.quiet-tests     := True
---
[00:48:03] .................................................................................i..................
[00:48:09] ........................i...........................................................................
---
[00:48:52] .......................i...........................................................................i
[00:48:58] ....................................................................................................
[00:49:05] .............ii.....................................................................................
---
[00:49:52] .............................................i......................................................
[00:50:12] ....................................................................................................
[00:50:29] ....................................................................................................
[00:50:45] ...............................................................F....................................
---
[00:53:55] ..............................i.....................................................................
[00:54:10] ...............................................................i....................................
[00:54:25] .................................................i..................................................
[00:54:46] ....................................................................................................
[00:55:07] ....................................................................................................
[00:55:29] ....................................................................................................
[00:55:55] .......i............................................................................................
[00:56:22] ...i.............................................................................test [run-pass] run-pass/mir_heavy_promoted.rs has been running for over 60 seconds
[00:56:32] ...................
[00:57:05] ....................................................................................................
[00:57:37] .....................................................................ii.............................
[00:58:28] ................................i.................................................test [run-pass] run-pass/saturating-float-casts.rs has been running for over 60 seconds
[00:58:35] ...i.ii...........
[00:59:19] .............................................................................................iiiiiii
[00:59:49] ....................................................................................................
[01:00:18] ....................................................................................................
[01:00:42] ....................................................................................................
---------------
[01:01:00]
[01:01:00] thread '[run-pass] run-pass/derive-partialord-correctness.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:2919:9
---
[01:01:00] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/run-pass" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "run-pass" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "3.9.1\n" "--system-llvm"Tue, 17 Apr 2018 01:26:13 GMT

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

// `self.fi.partial_cmp(other.fi)`
let cmp = cx.expr_method_call(span,
cx.expr_addr_of(span, self_f),
Ident::from_str("partial_cmp"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this avoid using an inherent partial_cmp method if the underlying type doesn't actually implement PartialOrd?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be PartialOrd::partial_cmp(...) - like Clone::clone deriving (IIRC).


let default = ordering_path(cx, "Equal");
// `_.unwrap_or(Ordering::Equal)`
cx.expr_method_call(span, cmp, Ident::from_str("unwrap_or"), vec![default])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not sure about what happens if there is a trait implemented by Option<Ordering> in scope with an unwrap_or method.

@SimonSapin
Copy link
Contributor

@Manishearth did you mean to r+, if this needs additional tests?

Additionally for nox’s concern (which I think suggest to use UFCS, like other derives seem to do), and for tests failing on Travis, let’s remove this from the queue for now:

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 17, 2018
@Manishearth
Copy link
Member

Manishearth commented Apr 17, 2018

Nah, I was asking for this to be manually tested and we can land the tests later if we wish. But yeah we should probably have the tests part of this before landing itself.

I'll defer to @nox though

@bors delegate=nox

@bors
Copy link
Collaborator

bors commented Apr 17, 2018

✌️ @nox can now approve this pull request

1 similar comment
@bors
Copy link
Collaborator

bors commented Apr 17, 2018

✌️ @nox can now approve this pull request

@varkor
Copy link
Member Author

varkor commented Apr 17, 2018

I think there's actually a good range of tests for this already — that's why the previous commits were caught. I just... might not... have been running all the tests before pushing... 😳

I think everything's passing now, but let's wait for Travis to confirm. PartialOrd is a tricky one.

@kennytm
Copy link
Member

kennytm commented Apr 18, 2018

(Travis passed)

@pietroalbini
Copy link
Member

Ping from triage @nox! You are now delegated to review this PR!

// )
// self.f1.partial_cmp(other.f1).unwrap_or(Ordering::Equal)
// .then_with(|| self.f2.partial_cmp(other.f2).unwrap_or(Ordering::Equal))
// != Ordering::Greater
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO those should just emit nested match expressions that return false directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there be any direct advantage to doing so? The main reason I used functions was because of the existing issues with match codegen efficiency, but I don't see that it makes a huge difference either way.


let strict_ineq = cx.expr_binary(span, strict_op, self_f.clone(), other_f.clone());
// `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems outdated, given we now use UFCS.


let and = cx.expr_binary(span, BinOpKind::And, deleg_cmp, subexpr);
cx.expr_binary(span, BinOpKind::Or, strict_ineq, and)
// `self.fi.partial_cmp(other.fi).unwrap_or(Ordering::Equal).then_with(...)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems outdated, given we now use UFCS.

@varkor varkor force-pushed the partialord-opt-ii branch 2 times, most recently from 211ca31 to 228228c Compare April 24, 2018 21:02
@bors
Copy link
Collaborator

bors commented Apr 25, 2018

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

Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once.
@varkor varkor force-pushed the partialord-opt-ii branch from 228228c to 6805e5a Compare April 25, 2018 10:26
@varkor varkor added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 27, 2018
@shepmaster
Copy link
Member

Ping from triage, @nox! Looks like this is ready to review again.

@shepmaster
Copy link
Member

Nit: AFAIK it's not called UFCS anymore, but Fully-Qualified Syntax

@nox
Copy link
Contributor

nox commented May 9, 2018

I still don't like that this is not using proper match expressions. I'll defer to @Manishearth for the final review (not sure why he delegated me to review it anyway).

@pietroalbini
Copy link
Member

Ping from triage @Manishearth! This PR needs your review.

@Manishearth
Copy link
Member

I don't have time to review this rn, sorry.

@Manishearth
Copy link
Member

oh, the logic has already been reviewed for this

code looks good.

@bors r+

@bors
Copy link
Collaborator

bors commented May 14, 2018

📌 Commit 6805e5a has been approved by Manishearth

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 14, 2018
@kennytm
Copy link
Member

kennytm commented May 14, 2018

@bors p=0

@bors
Copy link
Collaborator

bors commented May 15, 2018

⌛ Testing commit 6805e5a with merge d711dc9...

bors added a commit that referenced this pull request May 15, 2018
Ensure derive(PartialOrd) is no longer accidentally exponential

Previously, two comparison operations would be generated for each field, each of which could delegate to another derived PartialOrd. Now we use ordering and optional chaining to ensure each pair of fields is only compared once, addressing #49650 (comment).

Closes #49505.

r? @Manishearth (sorry for changing it again so soon!)

Close #50755
@bors
Copy link
Collaborator

bors commented May 15, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: Manishearth
Pushing d711dc9 to master...

@bors bors merged commit 6805e5a into rust-lang:master May 15, 2018
@varkor varkor deleted the partialord-opt-ii branch May 15, 2018 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants