about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/attributes.rs
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2024-07-07 06:58:52 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2024-07-07 06:58:52 +0300
commit54556f49d368ba96a92fd6ec352cf6b12e9542ef (patch)
tree02942decc68e1d0157daec674fee81c2c9a425c0 /compiler/rustc_codegen_llvm/src/attributes.rs
parent6ba80a9f8dec0dc71a8c041c59f8363916a0d09d (diff)
downloadrust-54556f49d368ba96a92fd6ec352cf6b12e9542ef.tar.gz
rust-54556f49d368ba96a92fd6ec352cf6b12e9542ef.zip
Specialize `TrustedLen` for `Iterator::unzip()`
Don't check the capacity every time (and also for `Extend` for tuples, as this is how `unzip()` is implemented).

I did this with an unsafe method on `Extend` that doesn't check for growth (`extend_one_unchecked()`). I've marked it as perma-unstable currently, although we may want to expose it in the future so collections outside of std can benefit from it. Then specialize `Extend for (A, B)` for `TrustedLen` to call it.

It may seem that an alternative way of implementing this is to have a semi-public trait (`#[doc(hidden)]` public, so collections outside of core can implement it) for `extend()` inside tuples, and specialize it from collections. However, it is impossible due to limitations of `min_specialization`.

A concern that may arise with the current approach is that implementing `extend_one_unchecked()` correctly must also incur implementing `extend_reserve()`, otherwise you can have UB. This is a somewhat non-local safety invariant. However, I believe this is fine, since to have actual UB you must have unsafe code inside your `extend_one_unchecked()` that makes incorrect assumption, *and* not implement `extend_reserve()`. I've also documented this requirement.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/attributes.rs')
0 files changed, 0 insertions, 0 deletions