about summary refs log tree commit diff
path: root/src/libcore
AgeCommit message (Collapse)AuthorLines
2020-03-26permit negative impls for non-auto traitsNiko Matsakis-0/+9
2020-03-25Rollup merge of #70366 - cuviper:option-fuse, r=dtolnayDylan DPC-255/+344
Implement Fuse with Option The former `done` flag was roughly similar to an `Option` tag, but left the possibity of misuse. By using a real `Option`, we can set `None` when the iterator is exhausted, removing any way to call it again. We also allow niche layout this way, so the `Fuse` may be smaller. The `FusedIterator` specialization does want to ignore the possibility of exhaustion though, so it uses `unsafe { intrinsics::unreachable() }` to optimize that branch away. The entire `Fuse` implementation is now isolated in its own module to contain that unsafety. r? @scottmcm
2020-03-25impl TrustedRandomAccess for Fuse without FusedIteratorJosh Stone-2/+6
2020-03-24Rollup merge of #70234 - anp:tracked-std-traits, r=AmanieuMazdak Farrokhzad-0/+10
#[track_caller] on core::ops::{Index, IndexMut}. Applies the attribute to `core::ops::Index(Mut)` and enough std internals to cover the [functions listed in "tier 1" in the original RFC](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md#survey-of-panicking-standard-functions). Split out from #69251 to allow separate assessment of perf impact. To my knowledge, this is the last piece of implementing RFC 2091. Tracking issue: https://github.com/rust-lang/rust/issues/47809
2020-03-24Implement Fuse with OptionJosh Stone-255/+340
The former `done` flag was roughly similar to an `Option` tag, but left the possibity of misuse. By using a real `Option`, we can set `None` when the iterator is exhausted, removing any way to call it again. We also allow niche layout this way, so the `Fuse` may be smaller. The `FusedIterator` specialization does want to ignore the possibility of exhaustion though, so it uses `unsafe { intrinsics::unreachable() }` to optimize that branch away. The entire `Fuse` implementation is now isolated in its own module to contain that unsafety.
2020-03-24Rollup merge of #70267 - RalfJung:const-prop-unsup, r=oli-obk,wesleywiserMazdak Farrokhzad-1/+1
get rid of ConstPropUnsupported; use ZST marker structs instead This gets rid of yet another machine-specific error variant. r? @oli-obk
2020-03-23#[track_caller] on core::ops::{Index, IndexMut}.Adam Perry-0/+10
2020-03-23Rename remaining occurences of Void to Opaque.Ana-Maria Mihalache-2/+2
2020-03-22Auto merge of #69079 - CAD97:layout-of-ptr, r=RalfJungbors-0/+139
Allow calculating the layout behind a pointer There was some discussion around allowing this previously. This does make the requirement for raw pointers to have valid metadata exposed as part of the std API (as a safety invariant, not validity invariant), though I think this is not strictly necessarily required as of current. cc @rust-lang/wg-unsafe-code-guidelines Naming is hard; I picked the best "obvious" name I could come up with. If it's agreed that this is actually a desired API surface, I'll file a tracking issue and update the attributes.
2020-03-22Auto merge of #68820 - WaffleLapkin:remove_finished_from_map_while, ↵bors-57/+32
r=LukasKalbertodt Remove `finished` flag from `MapWhile` This PR removes `finished` flag from `MapWhile` as been proposed in https://github.com/rust-lang/rust/pull/66577#discussion_r370958025. This also resolves open questions of the tracking issue (#68537): - `MapWhile` can't implement both + `DoubleEndedIterator` (discussed in https://github.com/rust-lang/rust/pull/66577#discussion_r370947990 and following comments) + `FusedIterator` (this pr removes `finished` flag, so `MapWhile` isn't fused anymore) - Debug output (this pr removes `finished` flag, so there is no question in including it in debug output) r? @Mark-Simulacrum
2020-03-22get rid of ConstPropUnsupported; use ZST marker structs insteadRalf Jung-1/+1
2020-03-21Allow calculating the layout behind a pointerCAD97-0/+139
Let align/size_of_of_val intrinsics work on ptrs
2020-03-21slightly change the `Iterator::map_while` docsWaffle-14/+4
2020-03-21Rollup merge of #70187 - matthiaskrgr:cl2ppy, r=Mark-SimulacrumMazdak Farrokhzad-1/+1
more clippy fixes * remove redundant returns (clippy::needless_return) * remove redundant import (clippy::single_component_path_imports) * remove redundant format!() call (clippy::useless_format) * don't use ok() before calling expect() (clippy::ok_expect)
2020-03-21Rollup merge of #70166 - CDirkx:range-inclusive-derives, r=cramertjMazdak Farrokhzad-22/+2
Derive PartialEq, Eq and Hash for RangeInclusive The manual implementation of `PartialEq`, `Eq` and `Hash` for `RangeInclusive` was functionally equivalent to a derived implementation. This change removes the manual implementation and adds the respective derives. A side effect of this change is that the derives also add implementations for `StructuralPartialEq` and `StructuralEq`, which enables `RangeInclusive` to be used in const generics, closing #70155. This change is enabled by #68835, which changed the field `is_empty: Option<bool>` to `exhausted: bool` removing the need for *semantic* equality instead of *structural* equality. ## PartialEq original [`PartialEq`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L353-L359) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> { #[inline] fn eq(&self, other: &Self) -> bool { self.start == other.start && self.end == other.end && self.exhausted == other.exhausted } } ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx> crate::marker::StructuralPartialEq for RangeInclusive<Idx> {} #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::cmp::PartialEq> crate::cmp::PartialEq for RangeInclusive<Idx> { #[inline] fn eq(&self, other: &RangeInclusive<Idx>) -> bool { match *other { RangeInclusive { start: ref __self_1_0,end: ref __self_1_1, exhausted: ref __self_1_2 } => match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1, exhausted: ref __self_0_2 } => { (*__self_0_0) == (*__self_1_0) && (*__self_0_1) == (*__self_1_1) && (*__self_0_2) == (*__self_1_2) } }, } } #[inline] fn ne(&self, other: &RangeInclusive<Idx>) -> bool { match *other { RangeInclusive { start: ref __self_1_0, end: ref __self_1_1, exhausted: ref __self_1_2 } => match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1exhausted: ref __self_0_2 } => { (*__self_0_0) != (*__self_1_0) || (*__self_0_1) != (*__self_1_1) || (*__self_0_2) != (*__self_1_2) } }, } } } ``` These implementations both test for *structural* equality, with the same order of field comparisons, and the bound `Idx: PartialEq` is the same. ## Eq original [`Eq`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L361-L362) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: Eq> Eq for RangeInclusive<Idx> {} ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx> crate::marker::StructuralEq for RangeInclusive<Idx> {} #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::cmp::Eq> crate::cmp::Eq for RangeInclusive<Idx> { #[inline] #[doc(hidden)] fn assert_receiver_is_total_eq(&self) -> () { { let _: crate::cmp::AssertParamIsEq<Idx>; let _: crate::cmp::AssertParamIsEq<Idx>; let _: crate::cmp::AssertParamIsEq<bool>; } } } ``` These implementations are equivalent since `Eq` is just a marker trait and the bound `Idx: Eq` is the same. ## Hash original [`Hash`](https://github.com/rust-lang/rust/blob/f4c675c476c18b1a11041193f2f59d695b126bc8/src/libcore/ops/range.rs#L364-L371) implementation: ```rust #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: Hash> Hash for RangeInclusive<Idx> { fn hash<H: Hasher>(&self, state: &mut H) { self.start.hash(state); self.end.hash(state); self.exhausted.hash(state); } } ``` expanded derive implementation (using `cargo expand ops::range`): ```rust #[automatically_derived] #[allow(unused_qualifications)] #[stable(feature = "inclusive_range", since = "1.26.0")] impl<Idx: crate::hash::Hash> crate::hash::Hash for RangeInclusive<Idx> { fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) -> () { match *self { RangeInclusive { start: ref __self_0_0, end: ref __self_0_1, exhausted: ref __self_0_2 } => { crate::hash::Hash::hash(&(*__self_0_0), state); crate::hash::Hash::hash(&(*__self_0_1), state); crate::hash::Hash::hash(&(*__self_0_2), state) } } } } ``` These implementations are functionally equivalent, with the same order of field hashing, and the bound `Idx: Hash` is the same.
2020-03-21Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJungMazdak Farrokhzad-18/+0
Remove the call that makes miri fail Fixes the concern raised in https://github.com/rust-lang/rust/pull/69645/files#r392884274 cc @RalfJung
2020-03-21Rollup merge of #69997 - WaffleLapkin:option_zip, r=LukasKalbertodtMazdak Farrokhzad-0/+58
add `Option::{zip,zip_with}` methods under "option_zip" gate This PR introduces 2 methods - `Option::zip` and `Option::zip_with` with respective signatures: - zip: `(Option<T>, Option<U>) -> Option<(T, U)>` - zip_with: `(Option<T>, Option<U>, (T, U) -> R) -> Option<R>` Both are under the feature gate "option_zip". I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer `union` for example, but this is a keyword :( ) -------------------------------------------------------------------------------- Recently in a russian rust begginers telegram chat a newbie asked (translated): > Are there any methods for these conversions: > > 1. `(Option<A>, Option<B>) -> Option<(A, B)>` > 2. `Vec<Option<T>> -> Option<Vec<T>>` > > ? While second (2.) is clearly `vec.into_iter().collect::<Option<Vec<_>>()`, the first one isn't that clear. I couldn't find anything similar in the `core` and I've come to this solution: ```rust let tuple: (Option<A>, Option<B>) = ...; let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b))); ``` However this solution isn't "nice" (same for just `match`/`if let`), so I thought that this functionality should be in `core`.
2020-03-21Rollup merge of #69033 - jonas-schievink:resume-with-context, r=tmandryMazdak Farrokhzad-0/+78
Use generator resume arguments in the async/await lowering This removes the TLS requirement from async/await and enables it in `#![no_std]` crates. Closes https://github.com/rust-lang/rust/issues/56974 I'm not confident the HIR lowering is completely correct, there seem to be quite a few undocumented invariants in there. The `async-std` and tokio test suites are passing with these changes though.
2020-03-20remove redundant returns (clippy::needless_return)Matthias Krüger-1/+1
2020-03-20Auto merge of #69509 - RalfJung:debug-assert-write, r=eddybbors-3/+1
debug-assert ptr sanity in ptr::write This is a re-submission of the parts that we removed from https://github.com/rust-lang/rust/pull/69208 due to ["interesting" test failures](https://github.com/rust-lang/rust/pull/69208#issuecomment-591310437). Fixes https://github.com/rust-lang/rust/issues/53871 r? @Mark-Simulacrum @eddyb
2020-03-19Removed unused `Hasher` import.CDirkx-1/+1
2020-03-19Derive PartialEq, Eq and Hash for RangeInclusiveCDirkx-21/+1
The manual implementation of PartialEq, Eq and Hash for RangeInclusive was functionally equivalent to a derived implementation. This change removes the manual implementation and adds the respective derives. A side effect of this change is that the derives also add implementations for StructuralPartialEq and StructuralEq, which enables RangeInclusive to be used in const generics.
2020-03-19make "other" in docs of `Option::{zip,zip_with}` monofontWaffle-2/+2
2020-03-19Don't hard-code the vector length in the examples.Hrvoje Nikšić-4/+3
Co-Authored-By: lzutao <taolzu@gmail.com>
2020-03-19Minor re-wordings and typo fixes.Hrvoje Nikšić-8/+8
Co-Authored-By: Ralf Jung <post@ralfj.de>
2020-03-19Restore (and reword) the warning against passing invalid values to mem::forget.Hrvoje Niksic-17/+35
As pointed out by Ralf Jung, dangling references and boxes are undefined behavior as per https://doc.rust-lang.org/reference/behavior-considered-undefined.html and the Miri checker.
2020-03-19Clarify the relationship between `forget()` and `ManuallyDrop`.Hrvoje Niksic-11/+27
As discussed on reddit, this commit addresses two issues with the documentation of `mem::forget()`: * The documentation of `mem::forget()` can confuse the reader because of the discrepancy between usage examples that show correct usage and the accompanying text which speaks of the possibility of double-free. The text that says "if the panic occurs before `mem::forget` was called" refers to a variant of the second example that was never shown, modified to use `mem::forget` instead of `ManuallyDrop`. Ideally the documentation should show both variants, so it's clear what it's talking about. Also, the double free could be fixed just by placing `mem::forget(v)` before the construction of `s`. Since the lifetimes of `s` and `v` wouldn't overlap, there would be no point where panic could cause a double free. This could be mentioned, and contrasted against the more robust fix of using `ManuallyDrop`. * This sentence seems unjustified: "For some types, operations such as passing ownership (to a funcion like `mem::forget`) requires them to actually be fully owned right now [...]". Unlike C++, Rust has no move constructors, its moves are (possibly elided) bitwise copies. Even if you pass an invalid object to `mem::forget`, no harm should come to pass because `mem::forget` consumes the object and exists solely to prevent drop, so there no one left to observe the invalid state state.
2020-03-19Rollup merge of #70088 - tmiasko:atomic-copy, r=eddybMazdak Farrokhzad-15/+15
Use copy bound in atomic operations to generate simpler MIR
2020-03-19Rollup merge of #69929 - cuviper:unicode-13.0.0, r=Mark-SimulacrumMazdak Farrokhzad-445/+462
Regenerate tables for Unicode 13.0.0
2020-03-18Move the const-forget test into ui testsDutchGhost-18/+0
2020-03-18fixes to `Option::{zip,zip_with}`Waffle-11/+9
- remove `#[inline]` attributes (see https://github.com/rust-lang/rust/pull/69997#discussion_r393942617) - fill tracking issue in `#[unstable]` attributes - slightly improve the docs
2020-03-18add `Option::{zip,zip_with}` methods under "option_zip" gateWaffle-0/+60
This commit introduces 2 methods - `Option::zip` and `Option::zip_with` with respective signatures: - zip: `(Option<T>, Option<U>) -> Option<(T, U)>` - zip_with: `(Option<T>, Option<U>, (T, U) -> R) -> Option<R>` Both are under the feature gate "option_zip". I'm not sure about the name "zip", maybe we can find a better name for this. (I would prefer `union` for example, but this is a keyword :( ) -------------------------------------------------------------------------------- Recently in a russian rust begginers telegram chat a newbie asked (translated): > Are there any methods for these conversions: > > 1. `(Option<A>, Option<B>) -> Option<(A, B)>` > 2. `Vec<Option<T>> -> Option<Vec<T>>` > > ? While second (2.) is clearly `vec.into_iter().collect::<Option<Vec<_>>()`, the first one isn't that clear. I couldn't find anything similar in the `core` and I've come to this solution: ```rust let tuple: (Option<A>, Option<B>) = ...; let res: Option<(A, B)> = tuple.0.and_then(|a| tuple.1.map(|b| (a, b))); ``` However this solution isn't "nice" (same for just `match`/`if let`), so I thought that this functionality should be in `core`.
2020-03-18Auto merge of #68915 - timvermeulen:non_fused_iter, r=Amanieubors-9/+90
Fix bugs in Peekable and Flatten when using non-fused iterators I fixed a couple of bugs with regard to the `Peekable` and `Flatten`/`FlatMap` iterators when the underlying iterator isn't fused. For testing, I also added a `NonFused` iterator wrapper that panics when `next` or `next_back` is called on an iterator that has returned `None` before, which will hopefully make it easier to spot these mistakes in the future. ### Peekable `Peekable::next_back` was implemented as ```rust self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x)) ``` which is incorrect because when the `peeked` field is `Some(None)`, then `None` has already been returned from the inner iterator and what it returns from `next_back` can no longer be relied upon. `test_peekable_non_fused` tests this. ### Flatten When a `FlattenCompat` instance only has a `backiter` remaining (i.e. `self.frontiter` is `None` and `self.iter` is empty), then `next` will call `self.iter.next()` every time, so the `iter` field needs to be fused. I fixed it by giving it the type `Fuse<I>` instead of `I`, I think this is the only way to fix it. `test_flatten_non_fused_outer` tests this. Furthermore, previously `FlattenCompat::next` did not set `self.frontiter` to `None` after it returned `None`, which is incorrect when the inner iterator type isn't fused. I just delegated it to `try_fold` because that already handles it correctly. `test_flatten_non_fused_inner` tests this. r? @scottmcm
2020-03-18Use copy bound in atomic operations to generate simpler MIRTomasz Miąsko-15/+15
2020-03-17Add issue referenceJonas Schievink-1/+1
2020-03-17Clarify commentJonas Schievink-1/+1
2020-03-17Make `ResumeTy` contents privateJonas Schievink-1/+1
2020-03-17Remove useless derives on `GenFuture`Jonas Schievink-1/+0
Not sure why these were there, I guess because this type used to kind of be part of public API?
2020-03-17FormatJonas Schievink-1/+1
2020-03-17Add futures scaffolding to libcoreJonas Schievink-0/+79
2020-03-17Rollup merge of #69922 - RalfJung:less-intrinsic, r=oli-obkMazdak Farrokhzad-43/+5
implement zeroed and uninitialized with MaybeUninit This is the second attempt of doing such a change (first PR: https://github.com/rust-lang/rust/pull/62150). The last change [got reverted](https://github.com/rust-lang/rust/pull/63343) because it [caused](https://github.com/rust-lang/rust/issues/62825) some [issues](https://github.com/rust-lang/rust/issues/52898#issuecomment-512182438) in [code that incorrectly used these functions](https://github.com/erlepereira/x11-rs/issues/99). Since then, the [problematic code has been fixed](https://github.com/erlepereira/x11-rs/pull/101), and rustc [gained a lint](https://github.com/rust-lang/rust/pull/63346) that is able to detect many misuses of these functions statically and a [dynamic check that panics](https://github.com/rust-lang/rust/pull/66059) instead of causing UB for some incorrect uses. Fixes https://github.com/rust-lang/rust/issues/62825
2020-03-17Rollup merge of #70029 - jonas-schievink:bootstrap, r=CentrilMazdak Farrokhzad-31/+4
Bump the bootstrap compiler
2020-03-17Rollup merge of #69870 - petrochenkov:cfgacc, r=matthewjasperMazdak Farrokhzad-0/+21
expand: Implement something similar to `#[cfg(accessible(path))]` cc https://github.com/rust-lang/rust/issues/64797 The feature is implemented as a `#[cfg_accessible(path)]` attribute macro rather than as `#[cfg(accessible(path))]` because it needs to wait until `path` becomes resolvable, and `cfg` cannot wait, but macros can wait. Later we can think about desugaring or not desugaring `#[cfg(accessible(path))]` into `#[cfg_accessible(path)]`. This implementation is also incomplete in the sense that it never returns "false" from `cfg_accessible(path)`, it requires some tweaks to resolve, which is not quite ready to answer queries like this during early resolution. However, the most important part of this PR is not `cfg_accessible` itself, but expansion infrastructure for retrying expansions. Before this PR we could say "we cannot resolve this macro path, let's try it later", with this PR we can say "we cannot expand this macro, let's try it later" as well. This is a pre-requisite for - turning `#[derive(...)]` into a regular attribute macro, - properly supporting eager expansion for macros that cannot yet be resolved like ``` fn main() { println!(not_available_yet!()); } macro_rules! make_available { () => { #[macro_export] macro_rules! not_available_yet { () => { "Hello world!" } }} } make_available!(); ```
2020-03-17Add testsTim Vermeulen-0/+72
2020-03-17Fix FlattenCompat::{next, next_back}Tim Vermeulen-4/+6
2020-03-16Auto merge of #68970 - matthewjasper:min-spec, r=nikomatsakisbors-0/+1
Implement a feature for a sound specialization subset This implements a new feature (`min_specialization`) that restricts specialization to a subset that is reasonable for the standard library to use. The plan is to then: * Update `libcore` and `liballoc` to compile with `min_specialization`. * Add a lint to forbid use of `feature(specialization)` (and other unsound, type system extending features) in the standard library. * Fix the soundness issues around `specialization`. * Remove `min_specialization` The rest of this is an overview from a comment in this PR ## Basic approach To enforce this requirement on specializations we take the following approach: 1. Match up the substs for `impl2` so that the implemented trait and self-type match those for `impl1`. 2. Check for any direct use of `'static` in the substs of `impl2`. 3. Check that all of the generic parameters of `impl1` occur at most once in the *unconstrained* substs for `impl2`. A parameter is constrained if its value is completely determined by an associated type projection predicate. 4. Check that all predicates on `impl1` also exist on `impl2` (after matching substs). ## Example Suppose we have the following always applicable impl: ```rust impl<T> SpecExtend<T> for std::vec::IntoIter<T> { /* specialized impl */ } impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ } ``` We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is constrained to be `<I as Iterator>::Item`, so we check only `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The predicates of `impl1` are only `T: Sized`, which is also a predicate of impl2`. So this specialization is sound. ## Extensions Unfortunately not all specializations in the standard library are allowed by this. So there are two extensions to these rules that allow specializing on some traits. ### rustc_specialization_trait If a trait is always applicable, then it's sound to specialize on it. We check trait is always applicable in the same way as impls, except that step 4 is now "all predicates on `impl1` are always applicable". We require that `specialization` or `min_specialization` is enabled to implement these traits. ### rustc_specialization_marker There are also some specialization on traits with no methods, including the `FusedIterator` trait which is advertised as allowing optimizations. We allow marking marker traits with an unstable attribute that means we ignore them in point 3 of the checks above. This is unsound but we allow it in the short term because it can't cause use after frees with purely safe code in the same way as specializing on traits methods can. r? @nikomatsakis cc #31844 #67194
2020-03-16make mem::{zeroed,uninitialized} inline(always)Ralf Jung-2/+2
2020-03-16rather than removing const_forget_box, stick an attribute on it and explain ↵DutchGhost-0/+12
it cant be called in ctfe yet
2020-03-16The const_forget_box was unused, and doesns't add anything to test by itself.DutchGhost-8/+0
2020-03-16Remove the call that makes miri failDutchGhost-4/+0