-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Reduce the genericity of closures in the iterator traits #62429
Conversation
r? @cramertj (rust_highfive has picked a reviewer for you, use r? to override) |
For some context, rayon-rs/rayon#671 reported that it is fairly easy to get parallel iterators to exceed the type length limit. I opened rayon-rs/rayon#673 to reduce genericity in a few specific cases, which seems to help. I decided it might be worthwhile to try this on the standard library too, if only so I could get some feedback on this approach. I kind of wish the compiler could just figure this out, but that may be more difficult. |
☔ The latest upstream changes (presumably #62473) made this pull request unmergeable. Please resolve the merge conflicts. |
Have you had a chance to do any investigation to see if this benefit actually occurs, perhaps by looking at the generated LLVM IR or the resulting generated code? If so, consider adding a test for this to ensure that it isn't regressed in the future. |
There are overflow tests for
I verified manually beforehand that such duplication was happening, and that they weren't afterward. And I know in rayon-rs/rayon#673 that similar changes did reduce the type length. But yes, I can and should add codegen tests specifically for these aspects. |
Great, thanks! |
The deduplication is now tested in codegen. I had a hard time figuring out how to demonstrate the type length as-is, but I was able to do so with It's interesting though, because even if I crank up If the |
b057ced
to
7548974
Compare
As an external data point, I looked again at rayon#673 |
Ping from triage, any updates? @cramertj |
@bors r+ |
📌 Commit bbb4e2e has been approved by |
@bors rollup=never |
⌛ Testing commit bbb4e2e with merge 06f646dcc71e856eb76f4f0dcc14ca10b267839a... |
💥 Test timed out |
The timed-out build included an LLVM rebuild -- I guess we can retry? @bors retry |
@rust-lang/infra that notification doesn't make any sense -- Miri does not build, tests cannot possibly pass on Windows. |
Same goes for Clippy |
Is there an issue that tracks any attempts to improve how closures are compiled, such that changes like these aren't necessary anymore? It's effective, but it's a lot of boilerplate code... I'm also wondering whether a macro could give the same upsides without the visual clutter of turning all closures into functions. @cuviper Have you tried this, or thought about it? |
@timvermeulen I don't have a good answer for either of those questions, and I agree it's a pain. I suspect that improving how closures are compiled -- I guess inferring tighter generic parameters -- would be RFC territory. This would be sort of like RFC 2229 at the type level. If that's possible, I would be happy to see these changes go back to simpler closures again. As for a macro, at least for One saving grace is that I don't think we need to turn this PR into a general "avoid closures" advice for Rust developers. I think iterators are unusual in this respect, and especially iterator adaptors, to have complicated generic types but closures that only operate on a simpler item type. Parallel iterators in |
I don't think we need an RFC for this (at least not a language RFC, just an implementation one at best), since it doesn't actually change anything from a user perspective. I opened #63660 |
Isn't this #46477? We should revive those efforts and implement it as "polymorphic" codegen (still-generic over some parameters which aren't actually used), in a similar way to how "polymorphic" CTFE works with miri today. |
#46477 was closed, does that mean this is no longer necessary? |
The tail end of that bug was discussing additional work that would be needed to reduce |
Great, thank you. |
This comment has been minimized.
This comment has been minimized.
I've hidden the comment now that I've opened #81721. |
By default, closures inherit the generic parameters of their scope,
including
Self
. However, in most cases, the closures used to implementiterators don't need to be generic on the iterator type, only its
Item
type. We can reduce this genericity by redirecting such closures through
local functions.
This does make the closures more cumbersome to write, but it will
hopefully reduce duplication in their monomorphizations, as well as
their related type lengths.