Now that the necessary associated types exist for the `IntoIterator` trait this
commit stabilizes the trait as-is as well as all existing implementations.
Now that the necessary associated types exist for the `IntoIterator` trait this
commit stabilizes the trait as-is as well as all existing implementations.
`IntoIterator` now has an extra associated item:
``` rust
trait IntoIterator {
type Item;
type IntoIter: Iterator<Self=Self::Item>;
}
```
This lets you bind the iterator \"`Item`\" directly when writing generic functions:
``` rust
// hypothetical change, not included in this PR
impl Extend<T> for Vec<T> {
// you can now write
fn extend<I>(&mut self, it: I) where I: IntoIterator<Item=T> { .. }
// instead of
fn extend<I: IntoIterator>(&mut self, it: I) where I::IntoIter: Iterator<Item=T> { .. }
}
```
The downside is that now you have to write an extra associated type in your `IntoIterator` implementations:
``` diff
impl<T> IntoIterator for Vec<T> {
+ type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> { .. }
}
```
Because this breaks all downstream implementations of `IntoIterator`, this is a [breaking-change]
---
r? @aturon
It is not totally clear if we should just use whitespace, or if the full
unicode word-breaking algorithm is more correct. If there is demand we
can reconsider this decision (and consider the precise algorithm to use
in detail).
cc #15628.
This PR is an optimization of the `FromIterator` implementation of `Vec`
Benchmark: https://gist.github.com/alexcrichton/03d666159a28a80e7c70
Before:
test macro_repeat1 ... bench: 57 ns/iter (+/- 1)
test macro_repeat2 ... bench: 56 ns/iter (+/- 1)
test map_clone1 ... bench: 828 ns/iter (+/- 13)
test map_clone2 ... bench: 828 ns/iter (+/- 8)
test repeat1 ... bench: 1104 ns/iter (+/- 10)
test repeat2 ... bench: 1106 ns/iter (+/- 11)
After:
test macro_repeat1 ... bench: 75 ns/iter (+/- 21)
test macro_repeat2 ... bench: 59 ns/iter (+/- 31)
test map_clone1 ... bench: 34 ns/iter (+/- 22)
test map_clone2 ... bench: 52 ns/iter (+/- 21)
test repeat1 ... bench: 34 ns/iter (+/- 11)
test repeat2 ... bench: 33 ns/iter (+/- 12)
The idea behind this optimization is to avoid all bounds checks for space
already allocated into the vector. This may involve running the iterator twice,
but the first run of the iterator should be optimizable to a memcpy or memset if
possible.
The same treatment can in theory be applied to `Vec::extend` but the benchmarks
for that currently get *worse* if the change is applied. This appears to be some
LLVM optimizations going awry but it's seems prudent to land at least the
`collect` portion beforehand.
It is not totally clear if we should just use whitespace, or if the full
unicode word-breaking algorithm is more correct. If there is demand we
can reconsider this decision (and consider the precise algorithm to use
in detail).
cc #15628.
This PR is an optimization of the `FromIterator` implementation of `Vec`
Benchmark: https://gist.github.com/alexcrichton/03d666159a28a80e7c70
Before:
test macro_repeat1 ... bench: 57 ns/iter (+/- 1)
test macro_repeat2 ... bench: 56 ns/iter (+/- 1)
test map_clone1 ... bench: 828 ns/iter (+/- 13)
test map_clone2 ... bench: 828 ns/iter (+/- 8)
test repeat1 ... bench: 1104 ns/iter (+/- 10)
test repeat2 ... bench: 1106 ns/iter (+/- 11)
After:
test macro_repeat1 ... bench: 75 ns/iter (+/- 21)
test macro_repeat2 ... bench: 59 ns/iter (+/- 31)
test map_clone1 ... bench: 34 ns/iter (+/- 22)
test map_clone2 ... bench: 52 ns/iter (+/- 21)
test repeat1 ... bench: 34 ns/iter (+/- 11)
test repeat2 ... bench: 33 ns/iter (+/- 12)
The idea behind this optimization is to avoid all bounds checks for space
already allocated into the vector. This may involve running the iterator twice,
but the first run of the iterator should be optimizable to a memcpy or memset if
possible.
The same treatment can in theory be applied to `Vec::extend` but the benchmarks
for that currently get *worse* if the change is applied. This appears to be some
LLVM optimizations going awry but it's seems prudent to land at least the
`collect` portion beforehand.
There are a number of holes that the stability lint did not previously cover,
including:
* Types
* Bounds on type parameters on functions and impls
* Where clauses
* Imports
* Patterns (structs and enums)
These holes have all been fixed by overriding the `visit_path` function on the
AST visitor instead of a few specialized cases. This change also necessitated a
few stability changes:
* The `collections::fmt` module is now stable (it was already supposed to be).
* The `thread_local:👿:Key` type is now stable (it was already supposed to
be).
* The `std::rt::{begin_unwind, begin_unwind_fmt}` functions are now stable.
These are required via the `panic!` macro.
* The `std::old_io::stdio::{println, println_args}` functions are now stable.
These are required by the `print!` and `println!` macros.
* The `ops::{FnOnce, FnMut, Fn}` traits are now `#[stable]`. This is required to
make bounds with these traits stable. Note that manual implementations of
these traits are still gated by default, this stability only allows bounds
such as `F: FnOnce()`.
Closes#8962Closes#16360Closes#20327
There are a number of holes that the stability lint did not previously cover,
including:
* Types
* Bounds on type parameters on functions and impls
* Where clauses
* Imports
* Patterns (structs and enums)
These holes have all been fixed by overriding the `visit_path` function on the
AST visitor instead of a few specialized cases. This change also necessitated a
few stability changes:
* The `collections::fmt` module is now stable (it was already supposed to be).
* The `thread_local:👿:Key` type is now stable (it was already supposed to
be).
* The `std::rt::{begin_unwind, begin_unwind_fmt}` functions are now stable.
These are required via the `panic!` macro.
* The `std::old_io::stdio::{println, println_args}` functions are now stable.
These are required by the `print!` and `println!` macros.
* The `ops::{FnOnce, FnMut, Fn}` traits are now `#[stable]`. This is required to
make bounds with these traits stable. Note that manual implementations of
these traits are still gated by default, this stability only allows bounds
such as `F: FnOnce()`.
Additionally, the compiler now has special logic to ignore its own generated
`__test` module for the `--test` harness in terms of stability.
Closes#8962Closes#16360Closes#20327
[breaking-change]
This is a resurrection and heavy revision/expansion of a PR that pcwalton did to resolve#8861.
The most relevant, user-visible semantic change is this: #[unsafe_destructor] is gone. Instead, if a type expression for some value has a destructor, then any lifetimes referenced within that type expression must strictly outlive the scope of the value.
See discussion on https://github.com/rust-lang/rfcs/pull/769
Port `core::ptr::Unique` to have `PhantomData`. Add `PhantomData` to
`TypedArena` and `Vec` as well.
As a drive-by, switch `ptr::Unique` from a tuple-struct to a struct
with fields.
* Remove type parameters from `IteratorExt::cloned`
* Rename `IntoIterator::Iter` to `IntoIterator::IntoIter`
* Mark `IntoIterator::into_iter` as stable (but not the trait, only the method).
This is in preparation for stabilization of the `IntoIterator` trait. All
implementations and references to `Iter` need to be renamed to `IntoIter`.
[breaking-change]