-
Notifications
You must be signed in to change notification settings - Fork 182
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
Conversation
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
This includes `&T` and `Arc<T>`.
4b62b7c
to
6944f22
Compare
There was a problem hiding this 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)
@bors r+ |
📌 Commit 6944f22 has been approved by |
☀️ Test successful - checks-actions |
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.
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.