-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add 'core::array::from_fn' and 'core::array::try_from_fn' #75644
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
I use similar functions since some months. I'm glad to see some love for arrays in stdlib, once we have some const generics :-) |
I personally do not think that this method has enough advantages over
Considering that |
These functions should not be seen as Take, for example, With the above reasoning:
It is also worth mentioning that the ClippyAnother use-case is the #![forbid(clippy::expect, clippy::unwrap)]
fn main() {
let _arr: [i32; 10] = (0..).map(f).collect().unwrap(); // Error!
}
Like I said, these functions should be seen as complementary companions to |
But
Yeah, this is why I used
This is true, but I do not see how
That one is a downside I did not consider. While I personally do think these lints are rarely appropriate, there are situations where not using any In general I can think of 2 solutions which I personally prefer:
trait UnwrapExt {
type Inner;
fn guaranteed_unwrap(self) -> Self::Inner;
}
impl<T, E> UnwrapExt for Result<T, E> {
type Inner = T;
fn guaranteed_unwrap(self) -> T {
extern "C" {
fn failed_to_optimize_unwrap_branch_check();
}
// This causes a linker error if the unwrap isn't optimized away, should probably
// only be used if your crate does not have any dependencies.
self.unwrap_or_else(|_| failed_to_optimize_unwrap_branch_check())
}
}
|
As previously commented, these functions deal with a different type of problem and shouldn't interact with the If someone wants to use iterators to create arrays, then
|
A few thoughts here:
|
1 for |
☔ The latest upstream changes (presumably #76217) made this pull request unmergeable. Please resolve the merge conflicts. |
@c410-f3r Could you resolve the merge conflicts? |
6ff44b8
to
0acad64
Compare
@bors r- |
Thanks. An unfortunate oversight |
lets try this again... In the name of Hades I approve this commit! |
📌 Commit 85c4a52 has been approved by |
Add 'core::array::from_fn' and 'core::array::try_from_fn' These auxiliary methods fill uninitialized arrays in a safe way and are particularly useful for elements that don't implement `Default`. ```rust // Foo doesn't implement Default struct Foo(usize); let _array = core::array::from_fn::<_, _, 2>(|idx| Foo(idx)); ``` Different from `FromIterator`, it is guaranteed that the array will be fully filled and no error regarding uninitialized state will be throw. In certain scenarios, however, the creation of an **element** can fail and that is why the `try_from_fn` function is also provided. ```rust #[derive(Debug, PartialEq)] enum SomeError { Foo, } let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i)); assert_eq!(array, Ok([0, 1, 2, 3, 4])); let another_array = core::array::try_from_fn(|_| Err(SomeError::Foo)); assert_eq!(another_array, Err(SomeError::Foo)); ```
…laumeGomez Rollup of 6 pull requests Successful merges: - rust-lang#75644 (Add 'core::array::from_fn' and 'core::array::try_from_fn') - rust-lang#87528 (stack overflow handler specific openbsd change.) - rust-lang#88436 (std: Stabilize command_access) - rust-lang#89614 (Update to Unicode 14.0) - rust-lang#89664 (Add documentation to boxed conversions) - rust-lang#89700 (Fix invalid HTML generation for higher bounds) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
I've tried to use this from_fn, but its usefulness is limited by the index that's always usize (and when possible I prefer to avoid type casts). Is it possible and a good idea to make the index type (input of F) generic (defaulting to usize)? |
@leonardo-m Like it or not, the index type is always |
@leonardo-m Note that default type parameters on functions aren't a thing, so I don't think it could even work. |
jhpratt in my codebase I use various ways to reduce the frequency of casting for indexes. It isn't a fact of life like Death or Taxes. I've seen that a from_fn like this is usable in more places in my codebase: pub fn from_fn<Ti, To, F, const N: usize>(mut cb: F) -> [To; N]
where
Ti: ZeroSucc Copy,
F: FnMut(Ti) -> To,
{
let mut idx = Ti::ZERO;
[(); N].map(|_| {
let res = cb(idx);
idx.succ();
res
})
} The disadvantage is some kind of trait for Zero and successive, and in a subset of from_fn usages you need to specify the type: (Another factor that reduces the usefulness of |
Supposing that each iteration increases the counter, an |
I think a better place for discussing this than this merged PR would be the tracking issue: #89379 |
…ttmcm Stabilize `array_from_fn` ## Overall Stabilizes `core::array::from_fn` ~~and `core::array::try_from_fn`~~ to allow the creation of custom infallible ~~and fallible~~ arrays. Signature proposed for stabilization here, tweaked as requested in the meeting: ```rust // in core::array pub fn from_fn<T, const N: usize, F>(_: F) -> [T; N]; ``` Examples in https://doc.rust-lang.org/nightly/std/array/fn.from_fn.html ## History * On 2020-08-17, implementation was [proposed](rust-lang#75644). * On 2021-09-29, tracking issue was [created](rust-lang#89379). * On 2021-10-09, the proposed implementation was [merged](bc8ad24). * On 2021-12-03, the return type of `try_from_fn` was [changed](rust-lang#91286 (comment)). ## Considerations * It is being assumed that indices are useful and shouldn't be removed from the callbacks * The fact that `try_from_fn` returns an unstable type `R: Try` does not prevent stabilization. Although I'm honestly not sure about it. * The addition or not of repeat-like variants is orthogonal to this PR. These considerations are not ways of saying what is better or what is worse. In reality, they are an attempt to move things forward, anything really. cc rust-lang#89379
Stabilize `array_from_fn` ## Overall Stabilizes `core::array::from_fn` ~~and `core::array::try_from_fn`~~ to allow the creation of custom infallible ~~and fallible~~ arrays. Signature proposed for stabilization here, tweaked as requested in the meeting: ```rust // in core::array pub fn from_fn<T, const N: usize, F>(_: F) -> [T; N]; ``` Examples in https://doc.rust-lang.org/nightly/std/array/fn.from_fn.html ## History * On 2020-08-17, implementation was [proposed](rust-lang/rust#75644). * On 2021-09-29, tracking issue was [created](rust-lang/rust#89379). * On 2021-10-09, the proposed implementation was [merged](rust-lang-ci/rust@bc8ad24). * On 2021-12-03, the return type of `try_from_fn` was [changed](rust-lang/rust#91286 (comment)). ## Considerations * It is being assumed that indices are useful and shouldn't be removed from the callbacks * The fact that `try_from_fn` returns an unstable type `R: Try` does not prevent stabilization. Although I'm honestly not sure about it. * The addition or not of repeat-like variants is orthogonal to this PR. These considerations are not ways of saying what is better or what is worse. In reality, they are an attempt to move things forward, anything really. cc rust-lang/rust#89379
These auxiliary methods fill uninitialized arrays in a safe way and are particularly useful for elements that don't implement
Clone
,Copy
orDefault
.Different from
FromIterator
, it is guaranteed that the array will be fully filled and no error regarding uninitialized state will be throw. In certain scenarios, however, the creation of an element can fail and that is why thetry_from_fn
function is also provided.