135
135
//! is not allowed. For more guidance on working with box from unsafe code, see
136
136
//! [rust-lang/unsafe-code-guidelines#326][ucg#326].
137
137
//!
138
+ //! # Editions
139
+ //!
140
+ //! A special case exists for the implementation of `IntoIterator` for arrays on the Rust 2021
141
+ //! edition, as documented [here][array]. Unfortunately, it was later found that a similar
142
+ //! workaround should be added for boxed slices, and this was applied in the 2024 edition.
143
+ //!
144
+ //! Specifically, `IntoIterator` is implemented for `Box<[T]>` on all editions, but specific calls
145
+ //! to `into_iter()` for boxed slices will defer to the slice implementation on editions before
146
+ //! 2024:
147
+ //!
148
+ #![ cfg_attr( bootstrap, doc = "```rust,edition2021,ignore" ) ]
149
+ #![ cfg_attr( not( bootstrap) , doc = "```rust,edition2021" ) ]
150
+ //! // Rust 2015, 2018, and 2021:
151
+ //!
152
+ //! # #![allow(boxed_slice_into_iter)] // override our `deny(warnings)`
153
+ //! let boxed_slice: Box<[i32]> = vec![0; 3].into_boxed_slice();
154
+ //!
155
+ //! // This creates a slice iterator, producing references to each value.
156
+ //! for item in boxed_slice.into_iter().enumerate() {
157
+ //! let (i, x): (usize, &i32) = item;
158
+ //! println!("boxed_slice[{i}] = {x}");
159
+ //! }
160
+ //!
161
+ //! // The `boxed_slice_into_iter` lint suggests this change for future compatibility:
162
+ //! for item in boxed_slice.iter().enumerate() {
163
+ //! let (i, x): (usize, &i32) = item;
164
+ //! println!("boxed_slice[{i}] = {x}");
165
+ //! }
166
+ //!
167
+ //! // You can explicitly iterate a boxed slice by value using `IntoIterator::into_iter`
168
+ //! for item in IntoIterator::into_iter(boxed_slice).enumerate() {
169
+ //! let (i, x): (usize, i32) = item;
170
+ //! println!("boxed_slice[{i}] = {x}");
171
+ //! }
172
+ //! ```
173
+ //!
174
+ //! Similar to the array implementation, this may be modified in the future to remove this override,
175
+ //! and it's best to avoid relying on this edition-dependent behavior if you wish to preserve
176
+ //! compatibility with future versions of the compiler.
138
177
//!
139
178
//! [ucg#198]: https://github.com/rust-lang/unsafe-code-guidelines/issues/198
140
179
//! [ucg#326]: https://github.com/rust-lang/unsafe-code-guidelines/issues/326
@@ -165,6 +204,7 @@ use core::ops::{
165
204
} ;
166
205
use core:: pin:: Pin ;
167
206
use core:: ptr:: { self , addr_of_mut, NonNull , Unique } ;
207
+ use core:: slice;
168
208
use core:: task:: { Context , Poll } ;
169
209
170
210
#[ cfg( not( no_global_oom_handling) ) ]
@@ -177,6 +217,7 @@ use crate::raw_vec::RawVec;
177
217
use crate :: str:: from_boxed_utf8_unchecked;
178
218
#[ cfg( not( no_global_oom_handling) ) ]
179
219
use crate :: string:: String ;
220
+ use crate :: vec;
180
221
#[ cfg( not( no_global_oom_handling) ) ]
181
222
use crate :: vec:: Vec ;
182
223
@@ -2080,6 +2121,51 @@ impl<I> FromIterator<I> for Box<[I]> {
2080
2121
}
2081
2122
}
2082
2123
2124
+ /// This implementation is required to make sure that the `Box<[I]>: IntoIterator`
2125
+ /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2126
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2127
+ impl < I , A : Allocator > !Iterator for Box < [ I ] , A > { }
2128
+
2129
+ /// This implementation is required to make sure that the `&Box<[I]>: IntoIterator`
2130
+ /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2131
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2132
+ impl < ' a , I , A : Allocator > !Iterator for & ' a Box < [ I ] , A > { }
2133
+
2134
+ /// This implementation is required to make sure that the `&mut Box<[I]>: IntoIterator`
2135
+ /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
2136
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2137
+ impl < ' a , I , A : Allocator > !Iterator for & ' a mut Box < [ I ] , A > { }
2138
+
2139
+ // Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
2140
+ // hides this implementation from explicit `.into_iter()` calls on editions < 2024,
2141
+ // so those calls will still resolve to the slice implementation, by reference.
2142
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2143
+ impl < I , A : Allocator > IntoIterator for Box < [ I ] , A > {
2144
+ type IntoIter = vec:: IntoIter < I , A > ;
2145
+ type Item = I ;
2146
+ fn into_iter ( self ) -> vec:: IntoIter < I , A > {
2147
+ self . into_vec ( ) . into_iter ( )
2148
+ }
2149
+ }
2150
+
2151
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2152
+ impl < ' a , I , A : Allocator > IntoIterator for & ' a Box < [ I ] , A > {
2153
+ type IntoIter = slice:: Iter < ' a , I > ;
2154
+ type Item = & ' a I ;
2155
+ fn into_iter ( self ) -> slice:: Iter < ' a , I > {
2156
+ self . iter ( )
2157
+ }
2158
+ }
2159
+
2160
+ #[ stable( feature = "boxed_slice_into_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2161
+ impl < ' a , I , A : Allocator > IntoIterator for & ' a mut Box < [ I ] , A > {
2162
+ type IntoIter = slice:: IterMut < ' a , I > ;
2163
+ type Item = & ' a mut I ;
2164
+ fn into_iter ( self ) -> slice:: IterMut < ' a , I > {
2165
+ self . iter_mut ( )
2166
+ }
2167
+ }
2168
+
2083
2169
#[ cfg( not( no_global_oom_handling) ) ]
2084
2170
#[ stable( feature = "boxed_str_from_iter" , since = "CURRENT_RUSTC_VERSION" ) ]
2085
2171
impl FromIterator < char > for Box < str > {
0 commit comments