This commit is an implementation of [RFC 494][rfc] which removes the entire
`std::c_vec` module and redesigns the `std::c_str` module as `std::ffi`.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0494-c_str-and-c_vec-stability.md
The interface of the new `CString` is outlined in the linked RFC, the primary
changes being:
* The `ToCStr` trait is gone, meaning the `with_c_str` and `to_c_str` methods
are now gone. These two methods are replaced with a `CString::from_slice`
method.
* The `CString` type is now just a wrapper around `Vec<u8>` with a static
guarantee that there is a trailing nul byte with no internal nul bytes. This
means that `CString` now implements `Deref<Target = [c_char]>`, which is where
it gains most of its methods from. A few helper methods are added to acquire a
slice of `u8` instead of `c_char`, as well as including a slice with the
trailing nul byte if necessary.
* All usage of non-owned `CString` values is now done via two functions inside
of `std::ffi`, called `c_str_to_bytes` and `c_str_to_bytes_with_nul`. These
functions are now the one method used to convert a `*const c_char` to a Rust
slice of `u8`.
Many more details, including newly deprecated methods, can be found linked in
the RFC. This is a:
[breaking-change]
Closes#20444
This removes a large array of deprecated functionality, regardless of how
recently it was deprecated. The purpose of this commit is to clean out the
standard libraries and compiler for the upcoming alpha release.
Some notable compiler changes were to enable warnings for all now-deprecated
command line arguments (previously the deprecated versions were silently
accepted) as well as removing deriving(Zero) entirely (the trait was removed).
The distribution no longer contains the libtime or libregex_macros crates. Both
of these have been deprecated for some time and are available externally.
This modifies `Parser::eat_lt` to always split up `<<`s, instead of doing so only when a lifetime name followed or the `force` parameter (now removed) was `true`. This is because `Foo<<TYPE` is now a valid start to a type, whereas previously only `Foo<<LIFETIME` was valid.
This is a [breaking-change]. Change code that looks like this:
```rust
let x = foo as bar << 13;
```
to use parentheses, like this:
```rust
let x = (foo as bar) << 13;
```
Closes#17362.
This commit is an implementation of [RFC 503][rfc] which is a stabilization
story for the prelude. Most of the RFC was directly applied, removing reexports.
Some reexports are kept around, however:
* `range` remains until range syntax has landed to reduce churn.
* `Path` and `GenericPath` remain until path reform lands. This is done to
prevent many imports of `GenericPath` which will soon be removed.
* All `io` traits remain until I/O reform lands so imports can be rewritten all
at once to `std::io::prelude::*`.
This is a breaking change because many prelude reexports have been removed, and
the RFC can be consulted for the exact list of removed reexports, as well as to
find the locations of where to import them.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0503-prelude-stabilization.md
[breaking-change]
Closes#20068
This pass performs a second pass of stabilization through the `std::sync`
module, avoiding modules/types that are being handled in other PRs (e.g.
mutexes, rwlocks, condvars, and channels).
The following items are now stable
* `sync::atomic`
* `sync::atomic::ATOMIC_BOOL_INIT` (was `INIT_ATOMIC_BOOL`)
* `sync::atomic::ATOMIC_INT_INIT` (was `INIT_ATOMIC_INT`)
* `sync::atomic::ATOMIC_UINT_INIT` (was `INIT_ATOMIC_UINT`)
* `sync::Once`
* `sync::ONCE_INIT`
* `sync::Once::call_once` (was `doit`)
* C == `pthread_once(..)`
* Boost == `call_once(..)`
* Windows == `InitOnceExecuteOnce`
* `sync::Barrier`
* `sync::Barrier::new`
* `sync::Barrier::wait` (now returns a `bool`)
* `sync::Semaphore::new`
* `sync::Semaphore::acquire`
* `sync::Semaphore::release`
The following items remain unstable
* `sync::SemaphoreGuard`
* `sync::Semaphore::access` - it's unclear how this relates to the poisoning
story of mutexes.
* `sync::TaskPool` - the semantics of a failing task and whether a thread is
re-attached to a thread pool are somewhat unclear, and the
utility of this type in `sync` is question with respect to
the jobs of other primitives. This type will likely become
stable or move out of the standard library over time.
* `sync::Future` - futures as-is have yet to be deeply re-evaluated with the
recent core changes to Rust's synchronization story, and will
likely become stable in the future but are unstable until
that time comes.
[breaking-change]
This commit performs a second pass over the `std::thread_local` module. Most of
the functionality remains explicitly unstable, but the specific actions taken
were:
* `thread_local` is now stable
* `thread_local!` is now stable
* `thread_local::Key` is now stable
* `thread_local::Key::with` is now stable
* `thread_local::Key::destroyed` is deprecated in favor of a more general
`state` function
* `thread_local::Key::state` was added to query the three states that a key can
be in: uninitialized, valid, or destroyed. This function, and the
corresponding `State` enum, are both marked unstable as we may wish to expand
it later on.
* `thread_local::scoped` is entirely unstable. There hasn't been a whole lot of
usage of this module in the standard distribution, so it remains unstable at
this time.
Note that while the structure `Key` is marked stable, it is currently forced to
expose all of its implementation details due to the use of
construction-via-macro. The use of construction-via-macro is currently required
in order to place the `#[thread_local]` attribute on static in a
platform-specific manner. These stability attributes were assigned assuming that
it will be acceptable to tweak the implementation of `Key` in the future.
The new semantics of this function are that the callbacks are run when the *main
thread* exits, not when all threads have exited. This implies that other threads
may still be running when the `at_exit` callbacks are invoked and users need to
be prepared for this situation.
Users in the standard library have been audited in accordance to these new rules
as well.
Closes#20012
This commit performs a second pass for stabilization over the `std::ptr` module.
The specific actions taken were:
* The `RawPtr` trait was renamed to `PtrExt`
* The `RawMutPtr` trait was renamed to `PtrMutExt`
* The module name `ptr` is now stable.
* These functions were all marked `#[stable]` with no modification:
* `null`
* `null_mut`
* `swap`
* `replace`
* `read`
* `write`
* `PtrExt::is_null`
* `PtrExt::is_not_null`
* `PtrExt::offset`
* These functions remain unstable:
* `as_ref`, `as_mut` - the return value of an `Option` is not fully expressive
as null isn't the only bad value, and it's unclear
whether we want to commit to these functions at this
time. The reference/lifetime semantics as written are
also problematic in how they encourage arbitrary
lifetimes.
* `zero_memory` - This function is currently not used at all in the
distribution, and in general it plays a broader role in the
"working with unsafe pointers" story. This story is not yet
fully developed, so at this time the function remains
unstable for now.
* `read_and_zero` - This function remains unstable for largely the same
reasons as `zero_memory`.
* These functions are now all deprecated:
* `PtrExt::null` - call `ptr::null` or `ptr::null_mut` instead.
* `PtrExt::to_uint` - use an `as` expression instead.
This commit performs a second pass for stabilization over the `std::ptr` module.
The specific actions taken were:
* The `RawPtr` trait was renamed to `PtrExt`
* The `RawMutPtr` trait was renamed to `MutPtrExt`
* The module name `ptr` is now stable.
* These functions were all marked `#[stable]` with no modification:
* `null`
* `null_mut`
* `swap`
* `replace`
* `read`
* `write`
* `PtrExt::is_null`
* `PtrExt::offset`
* These functions remain unstable:
* `as_ref`, `as_mut` - the return value of an `Option` is not fully expressive
as null isn't the only bad value, and it's unclear
whether we want to commit to these functions at this
time. The reference/lifetime semantics as written are
also problematic in how they encourage arbitrary
lifetimes.
* `zero_memory` - This function is currently not used at all in the
distribution, and in general it plays a broader role in the
"working with unsafe pointers" story. This story is not yet
fully developed, so at this time the function remains
unstable for now.
* `read_and_zero` - This function remains unstable for largely the same
reasons as `zero_memory`.
* These functions are now all deprecated:
* `PtrExt::null` - call `ptr::null` or `ptr::null_mut` instead.
* `PtrExt::to_uint` - use an `as` expression instead.
* `PtrExt::is_not_null` - use `!p.is_null()` instead.
This commit is a second pass stabilization for the `std::comm` module,
performing the following actions:
* The entire `std::comm` module was moved under `std::sync::mpsc`. This movement
reflects that channels are just yet another synchronization primitive, and
they don't necessarily deserve a special place outside of the other
concurrency primitives that the standard library offers.
* The `send` and `recv` methods have all been removed.
* The `send_opt` and `recv_opt` methods have been renamed to `send` and `recv`.
This means that all send/receive operations return a `Result` now indicating
whether the operation was successful or not.
* The error type of `send` is now a `SendError` to implement a custom error
message and allow for `unwrap()`. The error type contains an `into_inner`
method to extract the value.
* The error type of `recv` is now `RecvError` for the same reasons as `send`.
* The `TryRecvError` and `TrySendError` types have had public reexports removed
of their variants and the variant names have been tweaked with enum
namespacing rules.
* The `Messages` iterator is renamed to `Iter`
This functionality is now all `#[stable]`:
* `Sender`
* `SyncSender`
* `Receiver`
* `std::sync::mpsc`
* `channel`
* `sync_channel`
* `Iter`
* `Sender::send`
* `Sender::clone`
* `SyncSender::send`
* `SyncSender::try_send`
* `SyncSender::clone`
* `Receiver::recv`
* `Receiver::try_recv`
* `Receiver::iter`
* `SendError`
* `RecvError`
* `TrySendError::{mod, Full, Disconnected}`
* `TryRecvError::{mod, Empty, Disconnected}`
* `SendError::into_inner`
* `TrySendError::into_inner`
This is a breaking change due to the modification of where this module is
located, as well as the changing of the semantics of `send` and `recv`. Most
programs just need to rename imports of `std::comm` to `std::sync::mpsc` and
add calls to `unwrap` after a send or a receive operation.
[breaking-change]
All of the current std::sync primitives have poisoning enable which means that
when a task fails inside of a write-access lock then all future attempts to
acquire the lock will fail. This strategy ensures that stale data whose
invariants are possibly not upheld are never viewed by other tasks to help
propagate unexpected panics (bugs in a program) among tasks.
Currently there is no way to test whether a mutex or rwlock is poisoned. One
method would be to duplicate all the methods with a sister foo_catch function,
for example. This pattern is, however, against our [error guidelines][errors].
As a result, this commit exposes the fact that a task has failed internally
through the return value of a `Result`.
[errors]: https://github.com/rust-lang/rfcs/blob/master/text/0236-error-conventions.md#do-not-provide-both-result-and-fail-variants
All methods now return a `LockResult<T>` or a `TryLockResult<T>` which
communicates whether the lock was poisoned or not. In a `LockResult`, both the
`Ok` and `Err` variants contains the `MutexGuard<T>` that is being returned in
order to allow access to the data if poisoning is not desired. This also means
that the lock is *always* held upon returning from `.lock()`.
A new type, `PoisonError`, was added with one method `into_guard` which can
consume the assertion that a lock is poisoned to gain access to the underlying
data.
This is a breaking change because the signatures of these methods have changed,
often incompatible ways. One major difference is that the `wait` methods on a
condition variable now consume the guard and return it in as a `LockResult` to
indicate whether the lock was poisoned while waiting. Most code can be updated
by calling `.unwrap()` on the return value of `.lock()`.
[breaking-change]
This commit is an implementation of [RFC 503][rfc] which is a stabilization
story for the prelude. Most of the RFC was directly applied, removing reexports.
Some reexports are kept around, however:
* `range` remains until range syntax has landed to reduce churn.
* `Path` and `GenericPath` remain until path reform lands. This is done to
prevent many imports of `GenericPath` which will soon be removed.
* All `io` traits remain until I/O reform lands so imports can be rewritten all
at once to `std::io::prelude::*`.
This is a breaking change because many prelude reexports have been removed, and
the RFC can be consulted for the exact list of removed reexports, as well as to
find the locations of where to import them.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0503-prelude-stabilization.md
[breaking-change]
Closes#20068
This breaks code that looks like this:
let x = foo as bar << 13;
Change such code to look like this:
let x = (foo as bar) << 13;
Closes#17362.
[breaking-change]
This flag is somewhat tied to the `unwind` module rather than the `thread_info`
module, so this commit moves it into that module as well as allowing the same OS
thread to call `unwind::try` multiple times. Previously once a thread panicked
its panic flag was never reset, even after exiting the panic handler.
This commit is part of a series that introduces a `std::thread` API to
replace `std::task`.
In the new API, `spawn` returns a `JoinGuard`, which by default will
join the spawned thread when dropped. It can also be used to join
explicitly at any time, returning the thread's result. Alternatively,
the spawned thread can be explicitly detached (so no join takes place).
As part of this change, Rust processes now terminate when the main
thread exits, even if other detached threads are still running, moving
Rust closer to standard threading models. This new behavior may break code
that was relying on the previously implicit join-all.
In addition to the above, the new thread API also offers some built-in
support for building blocking abstractions in user space; see the module
doc for details.
Closes#18000
[breaking-change]
This commit removes the runtime bookkeeping previously used to ensure
that all Rust tasks were joined before the runtime was shut down.
This functionality will be replaced by an RAII style `Thread` API, that
will also offer a detached mode.
Since this changes the semantics of shutdown, it is a:
[breaking-change]
This commit merges the `rustrt` crate into `std`, undoing part of the
facade. This merger continues the paring down of the runtime system.
Code relying on the public API of `rustrt` will break; some of this API
is now available through `std::rt`, but is likely to change and/or be
removed very soon.
[breaking-change]
This commit is a reimplementation of `std::sync` to be based on the
system-provided primitives wherever possible. The previous implementation was
fundamentally built on top of channels, and as part of the runtime reform it has
become clear that this is not the level of abstraction that the standard level
should be providing. This rewrite aims to provide as thin of a shim as possible
on top of the system primitives in order to make them safe.
The overall interface of the `std::sync` module has in general not changed, but
there are a few important distinctions, highlighted below:
* The condition variable type, `Condvar`, has been separated out of a `Mutex`.
A condition variable is now an entirely separate type. This separation
benefits users who only use one mutex, and provides a clearer distinction of
who's responsible for managing condition variables (the application).
* All of `Condvar`, `Mutex`, and `RWLock` are now directly built on top of
system primitives rather than using a custom implementation. The `Once`,
`Barrier`, and `Semaphore` types are still built upon these abstractions of
the system primitives.
* The `Condvar`, `Mutex`, and `RWLock` types all have a new static type and
constant initializer corresponding to them. These are provided primarily for C
FFI interoperation, but are often useful to otherwise simply have a global
lock. The types, however, will leak memory unless `destroy()` is called on
them, which is clearly documented.
* The `Condvar` implementation for an `RWLock` write lock has been removed. This
may be added back in the future with a userspace implementation, but this
commit is focused on exposing the system primitives first.
* The fundamental architecture of this design is to provide two separate layers.
The first layer is that exposed by `sys_common` which is a cross-platform
bare-metal abstraction of the system synchronization primitives. No attempt is
made at making this layer safe, and it is quite unsafe to use! It is currently
not exported as part of the API of the standard library, but the stabilization
of the `sys` module will ensure that these will be exposed in time. The
purpose of this layer is to provide the core cross-platform abstractions if
necessary to implementors.
The second layer is the layer provided by `std::sync` which is intended to be
the thinnest possible layer on top of `sys_common` which is entirely safe to
use. There are a few concerns which need to be addressed when making these
system primitives safe:
* Once used, the OS primitives can never be **moved**. This means that they
essentially need to have a stable address. The static primitives use
`&'static self` to enforce this, and the non-static primitives all use a
`Box` to provide this guarantee.
* Poisoning is leveraged to ensure that invalid data is not accessible from
other tasks after one has panicked.
In addition to these overall blanket safety limitations, each primitive has a
few restrictions of its own:
* Mutexes and rwlocks can only be unlocked from the same thread that they
were locked by. This is achieved through RAII lock guards which cannot be
sent across threads.
* Mutexes and rwlocks can only be unlocked if they were previously locked.
This is achieved by not exposing an unlocking method.
* A condition variable can only be waited on with a locked mutex. This is
achieved by requiring a `MutexGuard` in the `wait()` method.
* A condition variable cannot be used concurrently with more than one mutex.
This is guaranteed by dynamically binding a condition variable to
precisely one mutex for its entire lifecycle. This restriction may be able
to be relaxed in the future (a mutex is unbound when no threads are
waiting on the condvar), but for now it is sufficient to guarantee safety.
* Condvars now support timeouts for their blocking operations. The
implementation for these operations is provided by the system.
Due to the modification of the `Condvar` API, removal of the `std::sync::mutex`
API, and reimplementation, this is a breaking change. Most code should be fairly
easy to port using the examples in the documentation of these primitives.
[breaking-change]
Closes#17094Closes#18003
This PR adds some internal infrastructure to allow the private `std::sys` module to access internal representation details of `std::io`.
It then exposes those details in two new, platform-specific API surfaces: `std::os::unix` and `std::os::windows`.
To start with, these will provide the ability to extract file descriptors, HANDLEs, SOCKETs, and so on from `std::io` types.
More functionality, and more specific platforms (e.g. `std::os::linux`) will be added over time.
Closes#18897
It turns out that rustrt::at_exit() doesn't actually occur after all pthread
threads have exited (nor does atexit()), so there's not actually a known point
at which we can deallocate these keys. It's not super critical that we do so,
however, because we're about to exit anyway!
Closes#19280
This commit removes the `std::local_data` module in favor of a new
`std::thread_local` module providing thread local storage. The module provides
two variants of TLS: one which owns its contents and one which is based on
scoped references. Each implementation has pros and cons listed in the
documentation.
Both flavors have accessors through a function called `with` which yield a
reference to a closure provided. Both flavors also panic if a reference cannot
be yielded and provide a function to test whether an access would panic or not.
This is an implementation of [RFC 461][rfc] and full details can be found in
that RFC.
This is a breaking change due to the removal of the `std::local_data` module.
All users can migrate to the new thread local system like so:
thread_local!(static FOO: Rc<RefCell<Option<T>>> = Rc::new(RefCell::new(None)))
The old `local_data` module inherently contained the `Rc<RefCell<Option<T>>>` as
an implementation detail which must now be explicitly stated by users.
[rfc]: https://github.com/rust-lang/rfcs/pull/461
[breaking-change]
This commit adds a `AsInner` trait to `sys_common` and provides
implementations on many `std::io` types. This is a building block for
exposing platform-specific APIs that hook into `std::io` types.
Previously, the entire runtime API surface was publicly exposed, but
that is neither necessary nor desirable. This commit hides most of the
module, using librustrt directly as needed. The arrangement will need to
be revisited when rustrt is pulled into std.
[breaking-change]
This breaks code that referred to variant names in the same namespace as
their enum. Reexport the variants in the old location or alter code to
refer to the new locations:
```
pub enum Foo {
A,
B
}
fn main() {
let a = A;
}
```
=>
```
pub use self::Foo::{A, B};
pub enum Foo {
A,
B
}
fn main() {
let a = A;
}
```
or
```
pub enum Foo {
A,
B
}
fn main() {
let a = Foo::A;
}
```
[breaking-change]
This patch continues runtime removal by moving the tty implementations
into `sys`.
Because this eliminates APIs in `libnative` and `librustrt`, it is a:
[breaking-change]
This functionality is likely to be available publicly, in some form,
from `std` in the future.
This patch continues the runtime removal by moving and refactoring the
process implementation into the new `sys` module.
Because this eliminates APIs in `libnative` and `librustrt`, it is a:
[breaking-change]
This functionality is likely to be available publicly, in some form,
from `std` in the future.
This patch continues the runtime removal by moving
libnative::io::helper_thread into sys::helper_signal and
sys_common::helper_thread
Because this eliminates APIs in `libnative` and `librustrt`, it is a:
[breaking-change]
This functionality is likely to be available publicly, in some form,
from `std` in the future.
This patch continues the runtime removal by moving pipe and
networking-related code into `sys`.
Because this eliminates APIs in `libnative` and `librustrt`, it is a:
[breaking-change]
This functionality is likely to be available publicly, in some form,
from `std` in the future.
These modules will house the code that used to be part of the runtime system
in libnative. The `sys_common` module contains a few low-level but
cross-platform details. The `sys` module is set up using `#[cfg()]` to
include either a unix or windows implementation of a common API
surface. This API surface is *not* exported directly in `libstd`, but is
instead used to bulid `std::os` and `std::io`.
Ultimately, the low-level details in `sys` will be exposed in a
controlled way through a separate platform-specific surface, but that
setup is not part of this patch.