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

Fold by value, not by reference #660

Merged
merged 10 commits into from
Dec 5, 2020
Merged

Conversation

ecstatic-morse
Copy link
Contributor

@ecstatic-morse ecstatic-morse commented Dec 4, 2020

Resolves #642.

This might need some more work. I suspect there are unnecessary clones. Without familiarity with the code base I found it hard to choose between changing a function signature versus cloning the argument in some places. It should be pretty close though.

This abstraction requires folding by-reference instead of by-value.
Additionally, it hides a call to `skip_binders` without cleanly
encapsulating it, so it probably shouldn't exist at all. I assume it is
needed within `rustc`, but this workspace can just use `Binders`
directly.
`B` never gets folded, only `P`, and the `B::Result: Debug` is not used
Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

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

♥ Thanks for this. This looks good to me generally, and I definitely am not going to particular about clones. Many of these should be "free" when I::InternedTy: Copy.

(I'm much more inclined to just land this as-is and fix things in-tree than to try to nit-pick as a PR)

@jackh726
Copy link
Member

jackh726 commented Dec 5, 2020

@bors r+

@bors
Copy link
Collaborator

bors commented Dec 5, 2020

📌 Commit 6944f22 has been approved by jackh726

@bors
Copy link
Collaborator

bors commented Dec 5, 2020

⌛ Testing commit 6944f22 with merge a96af67...

@bors
Copy link
Collaborator

bors commented Dec 5, 2020

☀️ Test successful - checks-actions
Approved by: jackh726
Pushing a96af67 to master...

@bors bors merged commit a96af67 into rust-lang:master Dec 5, 2020
bors added a commit that referenced this pull request Dec 15, 2020
Optimize `Fold` impls for types on the heap

Resolves a FIXME in #660.

This PR implements the same optimization used by [`rustc`](https://github.com/rust-lang/rust/blob/5be3f9f10e9fd59ea03816840a6051413fbdefae/compiler/rustc_data_structures/src/functor.rs#L13) to avoid unnecessary heap allocations in `Fold` impls for types like `Box` and `Vec`. Chalk's `Fold` trait is more customizable than the one in `rustc`: it allows one type to be `folded` into a different one as well as for early return via a `Result`. Accordingly, types are checked for layout compatibility (size and alignment) before the optimization is enabled. Types with different layouts (as well as zero-sized types) use the original `Fold` impl. Also, care is taken to avoid leaking resources when failure occurs while folding a `Vec`, since this may happen not only due to panicking but also due to an early return.

AFAICT, Chalk doesn't have benchmarks, but the new code executes about 350,000 times while running the test suite, so I suspect there will be some benefit for e.g. `rust-analyzer`. That said, I'm not opposed to waiting for some benchmarking before merging this, since it adds some non-trivial (albeit nicely encapsulated) unsafe code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor Fold to take by value
3 participants