From 00d91298f671ae146cdbf60008a82bb3fe6f3813 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 21 Oct 2017 16:50:58 +0900 Subject: [PATCH 1/3] array_into_iter_move --- text/0000-array_into_iter_move.md | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 text/0000-array_into_iter_move.md diff --git a/text/0000-array_into_iter_move.md b/text/0000-array_into_iter_move.md new file mode 100644 index 00000000000..d6663f1ec08 --- /dev/null +++ b/text/0000-array_into_iter_move.md @@ -0,0 +1,66 @@ +- Feature Name: array_into_iter_move +- Start Date: 2017-10-21 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +Implement into_iter on array types (not reference, so it moves). + +# Motivation +[motivation]: #motivation + +Arrays are particularly useful in `flat_map`, but currently a Vec is required as a movable +iterator because arrays only have slice iterator semantics. Obviously this is not optimal. + +Now with `ManuallyDrop` implemented, it should be possible to implement moving into_iter on arrays. + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +You can convert an array into an iterator with move, just like Vec: + +```rust +for x in [1, 2] { + // x is {integer} instead of &{integer} +} +``` + +```rust +let v: Vec<_> = (0..5).flat_map(|x| [x, x*2]).collect(); +``` + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +Proposed implementation: + +- a type `array::IntoIter` is created. The `array::into_iter` method is implemented. +- Inside the method: + * Transmute the array so it has `ManuallyDrop` signature. This should be memory safe. + * Create a `IntoIter` struct with contents moved. +- Inside the iterator: + * Keep track of valid range (index) and move items out as `next()` is called. + * Don't forget to drop the items if the iterator itself is dropped in middle. + +# Drawbacks +[drawbacks]: #drawbacks + +This is not 100% backwards compatible as it changes the signature of into_iter (only if directly +called like below). A crater run is required. + +```rust +[1, 2].into_iter(); +// This was originally yielding references, but now values. +``` + +# Rationale and alternatives +[alternatives]: #alternatives + +TBD + +# Unresolved questions +[unresolved]: #unresolved-questions + +TBD \ No newline at end of file From 7aaafd570e5a6b6e61a309befe3f9ae2a0d59f9a Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 21 Oct 2017 23:13:21 +0900 Subject: [PATCH 2/3] Address review comments --- text/0000-array_into_iter_move.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/text/0000-array_into_iter_move.md b/text/0000-array_into_iter_move.md index d6663f1ec08..fb25fff7f10 100644 --- a/text/0000-array_into_iter_move.md +++ b/text/0000-array_into_iter_move.md @@ -38,11 +38,13 @@ Proposed implementation: - a type `array::IntoIter` is created. The `array::into_iter` method is implemented. - Inside the method: - * Transmute the array so it has `ManuallyDrop` signature. This should be memory safe. + * Wrap the array with `ManuallyDrop`. * Create a `IntoIter` struct with contents moved. - Inside the iterator: - * Keep track of valid range (index) and move items out as `next()` is called. - * Don't forget to drop the items if the iterator itself is dropped in middle. + * Keep track of valid range (index) and move (`ptr::read`) items out as `next()` is called. + * Don't forget to drop the items if the iterator itself is dropped in middle. This should be done with `drop_in_place`. + +We should add a lint for redundant Vec in clippy to promote the use of this. # Drawbacks [drawbacks]: #drawbacks @@ -63,4 +65,4 @@ TBD # Unresolved questions [unresolved]: #unresolved-questions -TBD \ No newline at end of file +- What should the type signature look like? Possibly utilizing const generics. \ No newline at end of file From 4c1505b342f04de06af2f25fe91b138b8973b190 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Mon, 13 Nov 2017 15:47:48 +0900 Subject: [PATCH 3/3] Address comments regarding generics and lint --- text/0000-array_into_iter_move.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/text/0000-array_into_iter_move.md b/text/0000-array_into_iter_move.md index fb25fff7f10..33f6920036e 100644 --- a/text/0000-array_into_iter_move.md +++ b/text/0000-array_into_iter_move.md @@ -36,15 +36,18 @@ let v: Vec<_> = (0..5).flat_map(|x| [x, x*2]).collect(); Proposed implementation: -- a type `array::IntoIter` is created. The `array::into_iter` method is implemented. +- a type `array::IntoIter` is created. The `array::into_iter` method is implemented. +- 0..32 variant is first implemented using macros, then migrated to const generics once it lands. - Inside the method: * Wrap the array with `ManuallyDrop`. * Create a `IntoIter` struct with contents moved. - Inside the iterator: * Keep track of valid range (index) and move (`ptr::read`) items out as `next()` is called. * Don't forget to drop the items if the iterator itself is dropped in middle. This should be done with `drop_in_place`. - -We should add a lint for redundant Vec in clippy to promote the use of this. + +Before this lands, a deprecation warning should be implemented in either rustc or clippy to minimize the breakage. (See below for compatibility issues.) + +We should also add a lint for redundant Vec usage (instead of array) in clippy to promote the use of this. # Drawbacks [drawbacks]: #drawbacks @@ -65,4 +68,4 @@ TBD # Unresolved questions [unresolved]: #unresolved-questions -- What should the type signature look like? Possibly utilizing const generics. \ No newline at end of file +TBD