for only half of the maximum size available on the architecture. This
allows vectors to keep expanding with those two methods until the amount
of bytes exceeds usize.
The collections debug helpers no longer prefix output with the
collection name, in line with the current conventions for Debug
implementations. Implementations that want to preserve the current
behavior can simply add a `try!(write!(fmt, "TypeName "));` at the
beginning of the `fmt` method.
[breaking-change]
The collections debug helpers no longer prefix output with the
collection name, in line with the current conventions for Debug
implementations. Implementations that want to preserve the current
behavior can simply add a `try!(write!(fmt, "TypeName "));` at the
beginning of the `fmt` method.
[breaking-change]
This is technically a breaking change as it deprecates and unstables some previously stable apis that were missed in the last round of deprecations.
[breaking change]
Replace zeroing-on-drop with filling-on-drop.
This is meant to set the stage for removing *all* zeroing and filling (on drop) in the future.
Note that the code is meant to be entirely abstract with respect to the particular values used for the drop flags: the final commit demonstrates how to go from zeroing-on-drop to filling-on-drop by changing the value of three constants (in two files).
See further discussion on the internals thread:
http://internals.rust-lang.org/t/attention-hackers-filling-drop/1715/11
[breaking-change] especially for structs / enums using `#[unsafe_no_drop_flag]`.
This is technically a breaking change as it deprecates and unstables
some previously stable apis that were missed in the last round of
deprecations.
[breaking change]
Refactored code so that the drop-flag values for initialized
(`DTOR_NEEDED`) versus dropped (`DTOR_DONE`) are given explicit names.
Add `mem::dropped()` (which with `DTOR_DONE == 0` is semantically the
same as `mem::zeroed`, but the point is that it abstracts away from
the particular choice of value for `DTOR_DONE`).
Filling-drop needs to use something other than `ptr::read_and_zero`,
so I added such a function: `ptr::read_and_drop`. But, libraries
should not use it if they can otherwise avoid it.
Fixes to tests to accommodate filling-drop.
Main motivation was to update docs for the removal or "demotion" of certain extension traits. The update to the slice docs was larger, since the text was largely outdated.
A lot has changed since this doc text was last touched up, and this is
just a minor edit. I remove the trait section entirely since we don't
use extension traits that much anymore, so there are no significant
trait hilights for this module.
Main access point of .split() and other similar methods are not using
the StrExt trait anymore, so update the libcore docs to reflect this
(because these docs are visible in libstd API documentation).
This permits all coercions to be performed in casts, but adds lints to warn in those cases.
Part of this patch moves cast checking to a later stage of type checking. We acquire obligations to check casts as part of type checking where we previously checked them. Once we have type checked a function or module, then we check any cast obligations which have been acquired. That means we have more type information available to check casts (this was crucial to making coercions work properly in place of some casts), but it means that casts cannot feed input into type inference.
[breaking change]
* Adds two new lints for trivial casts and trivial numeric casts, these are warn by default, but can cause errors if you build with warnings as errors. Previously, trivial numeric casts and casts to trait objects were allowed.
* The unused casts lint has gone.
* Interactions between casting and type inference have changed in subtle ways. Two ways this might manifest are:
- You may need to 'direct' casts more with extra type information, for example, in some cases where `foo as _ as T` succeeded, you may now need to specify the type for `_`
- Casts do not influence inference of integer types. E.g., the following used to type check:
```
let x = 42;
let y = &x as *const u32;
```
Because the cast would inform inference that `x` must have type `u32`. This no longer applies and the compiler will fallback to `i32` for `x` and thus there will be a type error in the cast. The solution is to add more type information:
```
let x: u32 = 42;
let y = &x as *const u32;
```
This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`.
r? @japaric
cc @aturon @Gankro
possible blanket impls and also triggers internal overflow. Add some
special cases for common uses (&&str, &String) for now; bounds-targeting
deref coercions are probably the right longer term answer.
This commit:
* Introduces `std::convert`, providing an implementation of
RFC 529.
* Deprecates the `AsPath`, `AsOsStr`, and `IntoBytes` traits, all
in favor of the corresponding generic conversion traits.
Consequently, various IO APIs now take `AsRef<Path>` rather than
`AsPath`, and so on. Since the types provided by `std` implement both
traits, this should cause relatively little breakage.
* Deprecates many `from_foo` constructors in favor of `from`.
* Changes `PathBuf::new` to take no argument (creating an empty buffer,
as per convention). The previous behavior is now available as
`PathBuf::from`.
* De-stabilizes `IntoCow`. It's not clear whether we need this separate trait.
Closes#22751Closes#14433
[breaking-change]
This commit marks as `#[stable]` the `Entry` types for the maps provided
by `std`. The main reason these had been left unstable previously was
uncertainty about an eventual trait design, but several plausible
designs have been proposed that all work fine with the current type definitions.
r? @Gankro
This commit removes the `IndexMut` impls on `HashMap` and `BTreeMap`, in
order to future-proof the API against the eventual inclusion of an
`IndexSet` trait.
Ideally, we would eventually be able to support:
```rust
map[owned_key] = val;
map[borrowed_key].mutating_method(arguments);
&mut map[borrowed_key];
```
but to keep the design space as unconstrained as possible, we do not
currently want to support `IndexMut`, in case some other strategy will
eventually be needed.
Code currently using mutating index notation can use `get_mut` instead.
[breaking-change]
Closes#23448
r? @Gankro
This commit removes the reexports of `old_io` traits as well as `old_path` types
and traits from the prelude. This functionality is now all deprecated and needs
to be removed to make way for other functionality like `Seek` in the `std::io`
module (currently reexported as `NewSeek` in the io prelude).
Closes#23377Closes#23378
This commit removes the `IndexMut` impls on `HashMap` and `BTreeMap`, in
order to future-proof the API against the eventual inclusion of an
`IndexSet` trait.
Ideally, we would eventually be able to support:
```rust
map[owned_key] = val;
map[borrowed_key].mutating_method(arguments);
&mut map[borrowed_key];
```
but to keep the design space as unconstrained as possible, we do not
currently want to support `IndexMut`, in case some other strategy will
eventually be needed.
Code currently using mutating index notation can use `get_mut` instead.
[breaking-change]
Closes#23448
This commit marks as `#[stable]` the `Entry` types for the maps provided
by `std`. The main reason these had been left unstable previously was
uncertainty about an eventual trait design, but several plausible
designs have been proposed that all work fine with the current type definitions.
This commit clarifies some of the unstable features in the `str` module by
moving them out of the blanket `core` and `collections` features.
The following methods were moved to the `str_char` feature which generally
encompasses decoding specific characters from a `str` and dealing with the
result. It is unclear if any of these methods need to be stabilized for 1.0 and
the most conservative route for now is to continue providing them but to leave
them as unstable under a more specific name.
* `is_char_boundary`
* `char_at`
* `char_range_at`
* `char_at_reverse`
* `char_range_at_reverse`
* `slice_shift_char`
The following methods were moved into the generic `unicode` feature as they are
specifically enabled by the `unicode` crate itself.
* `nfd_chars`
* `nfkd_chars`
* `nfc_chars`
* `graphemes`
* `grapheme_indices`
* `width`
This commit deprecates the `count`, `range` and `range_step` functions
in `iter`, in favor of range notation. To recover all existing
functionality, a new `step_by` adapter is provided directly on `ops::Range`
and `ops::RangeFrom`.
[breaking-change]
r? @alexcrichton
This commit deprecates the `count`, `range` and `range_step` functions
in `iter`, in favor of range notation. To recover all existing
functionality, a new `step_by` adapter is provided directly on `ops::Range`
and `ops::RangeFrom`.
[breaking-change]
This commit performs another pass over the `std::char` module for stabilization.
Some minor cleanup is performed such as migrating documentation from libcore to
libunicode (where the `std`-facing trait resides) as well as a slight
reorganiation in libunicode itself. Otherwise, the stability modifications made
are:
* `char::from_digit` is now stable
* `CharExt::is_digit` is now stable
* `CharExt::to_digit` is now stable
* `CharExt::to_{lower,upper}case` are now stable after being modified to return
an iterator over characters. While the implementation today has not changed
this should allow us to implement the full set of case conversions in unicode
where some characters can map to multiple when doing an upper or lower case
mapping.
* `StrExt::to_{lower,upper}case` was added as unstable for a convenience of not
having to worry about characters expanding to more characters when you just
want the whole string to get into upper or lower case.
This is a breaking change due to the change in the signatures of the
`CharExt::to_{upper,lower}case` methods. Code can be updated to use functions
like `flat_map` or `collect` to handle the difference.
[breaking-change]
Closes#20333
This commit performs another pass over the `std::char` module for stabilization.
Some minor cleanup is performed such as migrating documentation from libcore to
libunicode (where the `std`-facing trait resides) as well as a slight
reorganiation in libunicode itself. Otherwise, the stability modifications made
are:
* `char::from_digit` is now stable
* `CharExt::is_digit` is now stable
* `CharExt::to_digit` is now stable
* `CharExt::to_{lower,upper}case` are now stable after being modified to return
an iterator over characters. While the implementation today has not changed
this should allow us to implement the full set of case conversions in unicode
where some characters can map to multiple when doing an upper or lower case
mapping.
* `StrExt::to_{lower,upper}case` was added as unstable for a convenience of not
having to worry about characters expanding to more characters when you just
want the whole string to get into upper or lower case.
This is a breaking change due to the change in the signatures of the
`CharExt::to_{upper,lower}case` methods. Code can be updated to use functions
like `flat_map` or `collect` to handle the difference.
[breaking-change]
This may not be quite ready to go out, I fixed some docs but suspect I missed a bunch.
I also wound up fixing a bunch of redundant `[]` suffixes, but on closer inspection I don't believe that can land until after a snapshot.
This is the kind of change that one is expected to need to make to
accommodate overloaded-`box`.
----
Note that this is not *all* of the changes necessary to accommodate
Issue 22181. It is merely the subset of those cases where there was
already a let-binding in place that made it easy to add the necesasry
type ascription.
(For unnamed intermediate `Box` values, one must go down a different
route; `Box::new` is the option that maximizes portability, but has
potential inefficiency depending on whether the call is inlined.)
----
There is one place worth note, `run-pass/coerce-match.rs`, where I
used an ugly form of `Box<_>` type ascription where I would have
preferred to use `Box::new` to accommodate overloaded-`box`. I
deliberately did not use `Box::new` here, because that is already done
in coerce-match-calls.rs.
----
Precursor for overloaded-`box` and placement-`in`; see Issue 22181.
Rebase and follow-through on work done by @cmr and @aatch.
Implements most of rust-lang/rfcs#560. Errors encountered from the checks during building were fixed.
The checks for division, remainder and bit-shifting have not been implemented yet.
See also PR #20795
cc @Aatch ; cc @nikomatsakis
This changes the type of some public constants/statics in libunicode.
Notably some `&'static &'static [(char, char)]` have changed
to `&'static [(char, char)]`. The regexp crate seems to be the
sole user of these, yet this is technically a [breaking-change]
* The lint visitor's visit_ty method did not recurse, and had a
reference to the now closed#10894
* The newly enabled recursion has only affected the `deprectated` lint
which now detects uses of deprecated items in trait impls and
function return types
* Renamed some references to `CowString` and `CowVec` to `Cow<str>` and
`Cow<[T]>`, respectively, which appear outside of the crate which
defines them
* Replaced a few instances of `InvariantType<T>` with
`PhantomData<Cell<T>>`
* Disabled the `deprecated` lint in several places that
reference/implement traits on deprecated items which will get cleaned
up in the future
* Unfortunately, this means that if a library declares
`#![deny(deprecated)]` and marks anything as deprecated, it will have
to disable the lint for any uses of said item, e.g. any impl the now
deprecated item
For any library that denies deprecated items but has deprecated items
of its own, this is a [breaking-change]
I had originally intended for the lint to ignore uses of deprecated items that are declared in the same crate, but this goes against some previous test cases that expect the lint to capture *all* uses of deprecated items, so I maintained the previous approach to avoid changing the expected behavior of the lint.
Tested locally on OS X, so hopefully there aren't any deprecated item uses behind a `cfg` that I may have missed.
* `collections::btree::node`: accommodate (transient) underflow.
* `collections::btree::map`: avoid underflow during `fn next`
for `BTreeMap::range` methods.
* `collections::slice`: note that pnkfelix deliberately used
`new_pos_wrapping` only once; the other cases of arithmetic do not
over- nor underflow, which is a useful property to leave implicitly
checked/documented via the remaining calls to `fn new_pos(..)`.
* `collections::vec_deque` applied wrapping ops (somewhat blindly)
to two implementation methods, and many tests.
* `std::collections:#️⃣:table` : Use `OverflowingOps` trait to
track overflow during `calculate_offsets` and `calculate_allocation`
functions.
Many of the core rust libraries have places that rely on integer
wrapping behaviour. These places have been altered to use the wrapping_*
methods:
* core:#️⃣:sip - A number of macros
* core::str - The `maximal_suffix` method in `TwoWaySearcher`
* rustc::util::nodemap - Implementation of FnvHash
* rustc_back::sha2 - A number of macros and other places
* rand::isaac - Isaac64Rng, changed to use the Wrapping helper type
Some places had "benign" underflow. This is when underflow or overflow
occurs, but the unspecified value is not used due to other conditions.
* collections::bit::Bitv - underflow when `self.nbits` is zero.
* collections:#️⃣:{map,table} - Underflow when searching an empty
table. Did cause undefined behaviour in this case due to an
out-of-bounds ptr::offset based on the underflowed index. However the
resulting pointers would never be read from.
* syntax::ext::deriving::encodable - Underflow when calculating the
index of the last field in a variant with no fields.
These cases were altered to avoid the underflow, often by moving the
underflowing operation to a place where underflow could not happen.
There was one case that relied on the fact that unsigned arithmetic and
two's complement arithmetic are identical with wrapping semantics. This
was changed to use the wrapping_* methods.
Finally, the calculation of variant discriminants could overflow if the
preceeding discriminant was `U64_MAX`. The logic in `rustc::middle::ty`
for this was altered to avoid the overflow completely, while the
remaining places were changed to use wrapping methods. This is because
`rustc::middle::ty::enum_variants` now throws an error when the
calculated discriminant value overflows a `u64`.
This behaviour can be triggered by the following code:
```
enum Foo {
A = U64_MAX,
B
}
```
This commit also implements the remaining integer operators for
Wrapped<T>.
* count_ones/zeros, trailing_ones/zeros return u32, not usize
* rotate_left/right take u32, not usize
* RADIX, MANTISSA_DIGITS, DIGITS, BITS, BYTES are u32, not usize
Doesn't touch pow because there's another PR for it.
[breaking-change]
* The lint visitor's visit_ty method did not recurse, and had a
reference to the now closed#10894
* The newly enabled recursion has only affected the `deprectated` lint
which now detects uses of deprecated items in trait impls and
function return types
* Renamed some references to `CowString` and `CowVec` to `Cow<str>` and
`Cow<[T]>`, respectively, which appear outside of the crate which
defines them
* Replaced a few instances of `InvariantType<T>` with
`PhantomData<Cell<T>>`
* Disabled the `deprecated` lint in several places that
reference/implement traits on deprecated items which will get cleaned
up in the future
* Disabled the `exceeding_bitshifts` lint for
compile-fail/huge-array-simple test so it doesn't shadow the expected
error on 32bit systems
* Unfortunately, this means that if a library declares
`#![deny(deprecated)]` and marks anything as deprecated, it will have
to disable the lint for any uses of said item, e.g. any impl the now
deprecated item
For any library that denies deprecated items but has deprecated items
of its own, this is a [breaking-change]
This changes the type of some public constants/statics in libunicode.
Notably some `&'static &'static [(char, char)]` have changed
to `&'static [(char, char)]`. The regexp crate seems to be the
sole user of these, yet this is technically a [breaking-change]
Specifically, the following actions were takend:
* The `copy_memory` and `copy_nonoverlapping_memory` functions
to drop the `_memory` suffix (as it's implied by the functionality). Both
functions are now marked as `#[stable]`.
* The `set_memory` function was renamed to `write_bytes` and is now stable.
* The `zero_memory` function is now deprecated in favor of `write_bytes`
directly.
* The `Unique` pointer type is now behind its own feature gate called `unique`
to facilitate future stabilization.
[breaking-change]
Specifically, the following actions were taken:
* The `copy_memory` and `copy_nonoverlapping_memory` functions
to drop the `_memory` suffix (as it's implied by the functionality). Both
functions are now marked as `#[stable]`.
* The `set_memory` function was renamed to `write_bytes` and is now stable.
* The `zero_memory` function is now deprecated in favor of `write_bytes`
directly.
* The `Unique` pointer type is now behind its own feature gate called `unique`
to facilitate future stabilization.
* All type parameters now are `T: ?Sized` wherever possible and new clauses were
added to the `offset` functions to require that the type is sized.
[breaking-change]
I tried to follow [the style guide][1] as much as possible. This is just from some random readings of the code, so no guarantees on completeness, even in the edited files.
[1]: http://aturon.github.io/style/README.html
e. g.
```
let b: Box<Foo> = Box::from_raw(p);
```
instead of
```
let b: Box<Foo> = mem::transmute(p);
```
Patch also changes closure release code in `src/libstd/sys/unix/thread.rs`
when `pthread_create` failed. Raw pointer was transmuted to box of
`FnOnce()` instead of `Thunk`. This code was probably never executed,
because `pthread_create` rarely fails.
(And there are two more patches in PR: fix typo in doc and mark `from_raw` and `into_raw` functions inline.)
... to convert between Box and raw pointers. E. g. use
```
let b: Box<Foo> = Box::from_raw(p);
```
instead of
```
let b: Box<Foo> = mem::transmute(p);
```
Patch also changes closure release code in `src/libstd/sys/unix/thread.rs`
when `pthread_create` failed. Raw pointer was transmuted to box of
`FnOnce()` instead of `Thunk`. This code was probably never executed,
because `pthread_create` rarely fails in practice.
This is not a complete implementation of the RFC:
- only existing methods got updated, no new ones added
- doc comments are not extensive enough yet
- optimizations got lost and need to be reimplemented
See https://github.com/rust-lang/rfcs/pull/528
Technically a
[breaking-change]
Implement both Vec::from_iter and extend in terms of an internal
method working with Iterator. Otherwise, the code below ends up
using two monomorphizations of extend, differing only in the
implementation of IntoIterator:
let mut v = Vector::from_iter(iterable1);
v.extend(iterable2);
Implements `append()` and `split_off()` for `VecMap`. It's worth noting
that `append()` will overwrite existing keys (the RFC doesn't specify how
`append()` should handle duplicate keys).
cc #19986
This commit stabilizes `std::borrow`, making the following modifications
to catch up the API with language changes:
* It renames `BorrowFrom` to `Borrow`, as was originally intended (but
blocked for technical reasons), and reorders the parameters
accordingly.
* It moves the type parameter of `ToOwned` to an associated type. This
is somewhat less flexible, in that each borrowed type must have a
unique owned type, but leads to a significant simplification for
`Cow`. Flexibility can be regained by using newtyped slices, which is
advisable for other reasons anyway.
* It removes the owned type parameter from `Cow`, making the type much
less verbose.
* Deprecates the `is_owned` and `is_borrowed` predicates in favor of
direct matching.
The above API changes are relatively minor; the basic functionality
remains the same, and essentially the whole module is now marked
`#[stable]`.
[breaking-change]
This commit is an implementation of [RFC 823][rfc] which is another pass over
the `std::hash` module for stabilization. The contents of the module were not
entirely marked stable, but some portions which remained quite similar to the
previous incarnation are now marked `#[stable]`. Specifically:
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0823-hash-simplification.md
* `std::hash` is now stable (the name)
* `Hash` is now stable
* `Hash::hash` is now stable
* `Hasher` is now stable
* `SipHasher` is now stable
* `SipHasher::new` and `new_with_keys` are now stable
* `Hasher for SipHasher` is now stable
* Many `Hash` implementations are now stable
All other portions of the `hash` module remain `#[unstable]` as they are less
commonly used and were recently redesigned.
This commit is a breaking change due to the modifications to the `std::hash` API
and more details can be found on the [RFC][rfc].
Closes#22467
[breaking-change]
This overlaps with #22276 (I left make check running overnight) but covers a number of additional cases and has a few rewrites where the clones are not even necessary.
This also implements `RandomAccessIterator` for `iter::Cloned`
cc @steveklabnik, you may want to glance at this before #22281 gets the bors treatment
This breaks all implementors of FromIterator, as they must now accept IntoIterator instead of Iterator. The fix for this is generally trivial (change the bound, and maybe call into_iter() on the argument to get the old argument).
Users of FromIterator should be unaffected because Iterators are IntoIterator.
[breaking-change]
This breaks all implementors of Extend, as they must now accept IntoIterator instead of Iterator. The fix for this is generally trivial (change the bound, and maybe call into_iter() on the argument to get the old argument).
Users of Extend should be unaffected because Iterators are IntoIterator.
[breaking-change]
This commit is an implementation of [RFC 823][rfc] which is another pass over
the `std::hash` module for stabilization. The contents of the module were not
entirely marked stable, but some portions which remained quite similar to the
previous incarnation are now marked `#[stable]`. Specifically:
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0823-hash-simplification.md
* `std::hash` is now stable (the name)
* `Hash` is now stable
* `Hash::hash` is now stable
* `Hasher` is now stable
* `SipHasher` is now stable
* `SipHasher::new` and `new_with_keys` are now stable
* `Hasher for SipHasher` is now stable
* Many `Hash` implementations are now stable
All other portions of the `hash` module remain `#[unstable]` as they are less
commonly used and were recently redesigned.
This commit is a breaking change due to the modifications to the `std::hash` API
and more details can be found on the [RFC][rfc].
Closes#22467
[breaking-change]
The data pointer used in the slice is never null, using assume() to tell
LLVM about it gets rid of various unneeded null checks when iterating
over the slice.
Since the snapshot compiler is still using an older LLVM version, omit
the call in stage0, because compile times explode otherwise.
Benchmarks from #18193
````
running 5 tests
test _range ... bench: 33329 ns/iter (+/- 417)
test assembly ... bench: 33299 ns/iter (+/- 58)
test enumerate ... bench: 33318 ns/iter (+/- 83)
test iter ... bench: 33311 ns/iter (+/- 130)
test position ... bench: 33300 ns/iter (+/- 47)
test result: ok. 0 passed; 0 failed; 0 ignored; 5 measured
````
Fixes#18193
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]
New functions, `slice::from_raw_parts` and `slice::from_raw_parts_mut`,
are added to implement the lifetime convention as agreed in rust-lang/rfcs#556.
The functions `slice::from_raw_buf` and `slice::from_raw_mut_buf` are
left deprecated for the time being.
Holding back on changing the signature of `std::ffi::c_str_to_bytes` as consensus in rust-lang/rfcs#592 is building to replace it with a composition of other functions.
Contribution to #21923.
This is 99% burning ints to the ground, but I also got rid of useless annotations or made code more \"idiomatic\" as I went along. Mostly changes in tests.
This was particularly helpful in the time just after OIBIT's
implementation to make sure things that were supposed to be Copy
continued to be, but it's now creates a lot of noise for types that
intentionally don't want to be Copy.
r? @alexcrichton
This also removes two erroneous re-exports of the Entry variants, and so is incidentally a [breaking-change], though presumably no one should have been using those.
r? @aturon
New functions, slice::from_raw_parts and slice::from_raw_parts_mut,
are added to implement the lifetime convention as agreed in RFC PR #556.
The functions slice::from_raw_buf and slice::from_raw_mut_buf are
left deprecated for the time being.
This was particularly helpful in the time just after OIBIT's
implementation to make sure things that were supposed to be Copy
continued to be, but it's now creates a lot of noise for types that
intentionally don't want to be Copy.
Building over night, posting for review now. Presumably not much should need change.
I consider this necessary to move forward with a proper stabilization of the API.
r? @huonw
Use the crates.io crate `rand` (version 0.1 should be a drop in
replacement for `std::rand`) and `rand_macros` (`#[derive_Rand]` should
be a drop-in replacement).
[breaking-change]
Now that associated types are fully implemented the iterator adaptors only need
type parameters which are associated with actual storage. All other type
parameters can either be derived from these (e.g. they are an associated type)
or can be bare on the `impl` block itself.
This is a breaking change due to the removal of type parameters on these
iterator adaptors, but code can fairly easily migrate by just deleting the
relevant type parameters for each adaptor. Other behavior should not be
affected.
Closes#21839
[breaking-change]
Now that associated types are fully implemented the iterator adaptors only need
type parameters which are associated with actual storage. All other type
parameters can either be derived from these (e.g. they are an associated type)
or can be bare on the `impl` block itself.
This is a breaking change due to the removal of type parameters on these
iterator adaptors, but code can fairly easily migrate by just deleting the
relevant type parameters for each adaptor. Other behavior should not be
affected.
Closes#21839
[breaking-change]
This commits adds an associated type to the `FromStr` trait representing an
error payload for parses which do not succeed. The previous return value,
`Option<Self>` did not allow for this form of payload. After the associated type
was added, the following attributes were applied:
* `FromStr` is now stable
* `FromStr::Err` is now stable
* `FromStr::from_str` is now stable
* `StrExt::parse` is now stable
* `FromStr for bool` is now stable
* `FromStr for $float` is now stable
* `FromStr for $integral` is now stable
* Errors returned from stable `FromStr` implementations are stable
* Errors implement `Display` and `Error` (both impl blocks being `#[stable]`)
Closes#15138
This commit performs a final stabilization pass over the std::fmt module,
marking all necessary APIs as stable. One of the more interesting aspects of
this module is that it exposes a good deal of its runtime representation to the
outside world in order for `format_args!` to be able to construct the format
strings. Instead of hacking the compiler to assume that these items are stable,
this commit instead lays out a story for the stabilization and evolution of
these APIs.
There are three primary details used by the `format_args!` macro:
1. `Arguments` - an opaque package of a "compiled format string". This structure
is passed around and the `write` function is the source of truth for
transforming a compiled format string into a string at runtime. This must be
able to be constructed in stable code.
2. `Argument` - an opaque structure representing an argument to a format string.
This is *almost* a trait object as it's just a pointer/function pair, but due
to the function originating from one of many traits, it's not actually a
trait object. Like `Arguments`, this must be constructed from stable code.
3. `fmt::rt` - this module contains the runtime type definitions primarily for
the `rt::Argument` structure. Whenever an argument is formatted with
nonstandard flags, a corresponding `rt::Argument` is generated describing how
the argument is being formatted. This can be used to construct an
`Arguments`.
The primary interface to `std::fmt` is the `Arguments` structure, and as such
this type name is stabilize as-is today. It is expected for libraries to pass
around an `Arguments` structure to represent a pending formatted computation.
The remaining portions are largely "cruft" which would rather not be stabilized,
but due to the stability checks they must be. As a result, almost all pieces
have been renamed to represent that they are "version 1" of the formatting
representation. The theory is that at a later date if we change the
representation of these types we can add new definitions called "version 2" and
corresponding constructors for `Arguments`.
One of the other remaining large questions about the fmt module were how the
pending I/O reform would affect the signatures of methods in the module. Due to
[RFC 526][rfc], however, the writers of fmt are now incompatible with the
writers of io, so this question has largely been solved. As a result the
interfaces are largely stabilized as-is today.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md
Specifically, the following changes were made:
* The contents of `fmt::rt` were all moved under `fmt::rt::v1`
* `fmt::rt` is stable
* `fmt::rt::v1` is stable
* `Error` is stable
* `Writer` is stable
* `Writer::write_str` is stable
* `Writer::write_fmt` is stable
* `Formatter` is stable
* `Argument` has been renamed to `ArgumentV1` and is stable
* `ArgumentV1::new` is stable
* `ArgumentV1::from_uint` is stable
* `Arguments::new_v1` is stable (renamed from `new`)
* `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`)
* All formatting traits are now stable, as well as the `fmt` method.
* `fmt::write` is stable
* `fmt::format` is stable
* `Formatter::pad_integral` is stable
* `Formatter::pad` is stable
* `Formatter::write_str` is stable
* `Formatter::write_fmt` is stable
* Some assorted top level items which were only used by `format_args!` were
removed in favor of static functions on `ArgumentV1` as well.
* The formatting-flag-accessing methods remain unstable
Within the contents of the `fmt::rt::v1` module, the following actions were
taken:
* Reexports of all enum variants were removed
* All prefixes on enum variants were removed
* A few miscellaneous enum variants were renamed
* Otherwise all structs, fields, and variants were marked stable.
In addition to these actions in the `std::fmt` module, many implementations of
`Show` and `String` were stabilized as well.
In some other modules:
* `ToString` is now stable
* `ToString::to_string` is now stable
* `Vec` no longer implements `fmt::Writer` (this has moved to `String`)
This is a breaking change due to all of the changes to the `fmt::rt` module, but
this likely will not have much impact on existing programs.
Closes#20661
[breaking-change]
This commits adds an associated type to the `FromStr` trait representing an
error payload for parses which do not succeed. The previous return value,
`Option<Self>` did not allow for this form of payload. After the associated type
was added, the following attributes were applied:
* `FromStr` is now stable
* `FromStr::Err` is now stable
* `FromStr::from_str` is now stable
* `StrExt::parse` is now stable
* `FromStr for bool` is now stable
* `FromStr for $float` is now stable
* `FromStr for $integral` is now stable
* Errors returned from stable `FromStr` implementations are stable
* Errors implement `Display` and `Error` (both impl blocks being `#[stable]`)
Closes#15138
the compiler that assumed two input types to assume two ouputs; we also have to teach `project.rs`
to project `Output` from the unboxed closure and fn traits.
Hi! I added some examples to some SliceExt methods that didn't have any.
I'm looking forward to feedback and I'm happy to change anything-- it looks like the doc conventions are still a bit in flux, based on the discussions going on in [rfc 505](https://github.com/rust-lang/rfcs/pull/505).
I was most unsure about examples for methods that return iterators over slices... I wanted to use asserts on the result of calling `.next()` like in [this permutations example](804c1446b3/src/libcollections/slice.rs (L608-L617)), but then it gets all cluttered up with lifetime stuff... so I went with iterating and printing and mentioning what the expected printed output is like in [this chunks example](804c1446b3/src/libcollections/slice.rs (L297-L304))... any ideas for the best ways to do this are appreciated.
Thank you! ❤️
Don't reallocate when capacity is already equal to length
`Vec::shrink_to_fit()` may be called on vectors that are already the
correct length. Calling out to `reallocate()` in this case is a bad idea
because there is no guarantee that `reallocate()` won't allocate a new
buffer anyway, and based on performance seen in external benchmarks, it
seems likely that it is in fact reallocating a new buffer.
Before:
test string::tests::bench_exact_size_shrink_to_fit ... bench: 45 ns/iter (+/- 2)
After:
test string::tests::bench_exact_size_shrink_to_fit ... bench: 26 ns/iter (+/- 1)