This commit is part of the ongoing libstd facade efforts (cc #13851). The
compiler now recognizes some language items as "extern { fn foo(...); }" and
will automatically perform the following actions:
1. The foreign function has a pre-defined name.
2. The crate and downstream crates can only be built as rlibs until a crate
defines the lang item itself.
3. The actual lang item has a pre-defined name.
This is essentially nicer compiler support for the hokey
core-depends-on-std-failure scheme today, but it is implemented the same way.
The details are a little more hidden under the covers.
In addition to failure, this commit promotes the eh_personality and
rust_stack_exhausted functions to official lang items. The compiler can generate
calls to these functions, causing linkage errors if they are left undefined. The
checking for these items is not as precise as it could be. Crates compiling with
`-Z no-landing-pads` will not need the eh_personality lang item, and crates
compiling with no split stacks won't need the stack exhausted lang item. For
ease, however, these items are checked for presence in all final outputs of the
compiler.
It is quite easy to define dummy versions of the functions necessary:
#[lang = "stack_exhausted"]
extern fn stack_exhausted() { /* ... */ }
#[lang = "eh_personality"]
extern fn eh_personality() { /* ... */ }
cc #11922, rust_stack_exhausted is now a lang item
cc #13851, libcollections is blocked on eh_personality becoming weak
This commit is part of the libstd facade RFC, issue #13851. This creates a new
library, liballoc, which is intended to be the core allocation library for all
of Rust. It is pinned on the basic assumption that an allocation failure is an
abort or failure.
This module has inherited the heap/libc_heap modules from std::rt, the owned/rc
modules from std, and the arc module from libsync. These three pointers are
currently the three most core pointer implementations in Rust.
The UnsafeArc type in std::sync should be considered deprecated and replaced by
Arc<Unsafe<T>>. This commit does not currently migrate to this type, but future
commits will continue this refactoring.
1. Wherever the `buf` field of a `Formatter` was used, the `Formatter` is used
instead.
2. The usage of `write_fmt` is minimized as much as possible, the `write!` macro
is preferred wherever possible.
3. Usage of `fmt::write` is minimized, favoring the `write!` macro instead.
Now that std::fmt is in libcore, it's possible to implement this as an inherit
method rather than through extension traits.
This commit also tweaks the failure interface of libcore to libstd to what it
should be, one method taking &fmt::Arguments
pthread_yield is non-standard, while sched_yield is POSIX
The Linux documentation recommends using the standard function. This is
the only feature we're currently using that's present in glibc but not
in musl.
The existing APIs for spawning processes took strings for the command
and arguments, but the underlying system may not impose utf8 encoding,
so this is overly limiting.
The assumption we actually want to make is just that the command and
arguments are viewable as [u8] slices with no interior NULLs, i.e., as
CStrings. The ToCStr trait is a handy bound for types that meet this
requirement (such as &str and Path).
However, since the commands and arguments are often a mixture of
strings and paths, it would be inconvenient to take a slice with a
single T: ToCStr bound. So this patch revamps the process creation API
to instead use a builder-style interface, called `Command`, allowing
arguments to be added one at a time with differing ToCStr
implementations for each.
The initial cut of the builder API has some drawbacks that can be
addressed once issue #13851 (libstd as a facade) is closed. These are
detailed as FIXMEs.
Closes#11650.
[breaking-change]
This implements set_timeout() for std::io::Process which will affect wait()
operations on the process. This follows the same pattern as the rest of the
timeouts emerging in std::io::net.
The implementation was super easy for everything except libnative on unix
(backwards from usual!), which required a good bit of signal handling. There's a
doc comment explaining the strategy in libnative. Internally, this also required
refactoring the "helper thread" implementation used by libnative to allow for an
extra helper thread (not just the timer).
This is a breaking change in terms of the io::Process API. It is now possible
for wait() to fail, and subsequently wait_with_output(). These two functions now
return IoResult<T> due to the fact that they can time out.
Additionally, the wait_with_output() function has moved from taking `&mut self`
to taking `self`. If a timeout occurs while waiting with output, the semantics
are undesirable in almost all cases if attempting to re-wait on the process.
Equivalent functionality can still be achieved by dealing with the output
handles manually.
[breaking-change]
cc #13523
The compiler was updated to recognize that implementations for ty_uniq(..) are
allowed if the Box lang item is located in the current crate. This enforces the
idea that libcore cannot allocated, and moves all related trait implementations
from libcore to libstd.
This is a breaking change in that the AnyOwnExt trait has moved from the any
module to the owned module. Any previous users of std::any::AnyOwnExt should now
use std::owned::AnyOwnExt instead. This was done because the trait is intended
for Box traits and only Box traits.
[breaking-change]
The `FileStat` struct contained a `path` field, which was filled by the
`stat` and `lstat` function. Since this field isn't in fact returned by
the operating system (it was copied from the paths passed to the
functions) it was removed, as in the `fstat` case we aren't working with
a `Path`, but directly with a fd.
If your code used the `path` field of `FileStat` you will now have to
manually store the path passed to `stat` along with the returned struct.
[breaking-change]
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.
* transmute - This function was moved to `mem`, but it is now marked as
#[unstable]. This is due to planned changes to the `transmute`
function and how it can be invoked (see the #[unstable] comment).
For more information, see RFC 5 and #12898
* transmute_copy - This function was moved to `mem`, with clarification that is
is not an error to invoke it with T/U that are different
sizes, but rather that it is strongly discouraged. This
function is now #[stable]
* forget - This function was moved to `mem` and marked #[stable]
* bump_box_refcount - This function was removed due to the deprecation of
managed boxes as well as its questionable utility.
* transmute_mut - This function was previously deprecated, and removed as part
of this commit.
* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
can be achieved with an `as` in safe code, so it was
removed.
* transmute_lifetime - This function was removed because it is likely a strong
indication that code is incorrect in the first place.
* transmute_mut_lifetime - This function was removed for the same reasons as
`transmute_lifetime`
* copy_lifetime - This function was moved to `mem`, but it is marked
`#[unstable]` now due to the likelihood of being removed in
the future if it is found to not be very useful.
* copy_mut_lifetime - This function was also moved to `mem`, but had the same
treatment as `copy_lifetime`.
* copy_lifetime_vec - This function was removed because it is not used today,
and its existence is not necessary with DST
(copy_lifetime will suffice).
In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.
transmute - #[unstable]
transmute_copy - #[stable]
forget - #[stable]
copy_lifetime - #[unstable]
copy_mut_lifetime - #[unstable]
[breaking-change]
In stage0, all allocations are 8-byte aligned. Passing a size and
alignment to free is not yet implemented everywhere (0 size and 8 align
are used as placeholders). Fixing this is part of #13994.
Closes#13616
This adds a `std::rt::heap` module with a nice allocator API. It's a
step towards fixing #13094 and is a starting point for working on a
generic allocator trait.
The revision used for the jemalloc submodule is the stable 3.6.0 release.
Closes#11807
This commit brings the local_data api up to modern rust standards with a few key
improvements:
* All functionality is now exposed as a method on the keys themselves. Instead
of importing std::local_data, you now use "key.set()" and "key.get()".
* All closures have been removed in favor of RAII functionality. This means that
get() and get_mut() no long require closures, but rather return
Option<SmartPointer> where the smart pointer takes care of relinquishing the
borrow and also implements the necessary Deref traits
* The modify() function was removed to cut the local_data interface down to its
bare essentials (similarly to how RefCell removed set/get).
[breaking-change]
This commit brings the local_data api up to modern rust standards with a few key
improvements:
* The `pop` and `set` methods have been combined into one method, `replace`
* The `get_mut` method has been removed. All interior mutability should be done
through `RefCell`.
* All functionality is now exposed as a method on the keys themselves. Instead
of importing std::local_data, you now use "key.replace()" and "key.get()".
* All closures have been removed in favor of RAII functionality. This means that
get() and get_mut() no long require closures, but rather return
Option<SmartPointer> where the smart pointer takes care of relinquishing the
borrow and also implements the necessary Deref traits
* The modify() function was removed to cut the local_data interface down to its
bare essentials (similarly to how RefCell removed set/get).
[breaking-change]
These timeouts all follow the same pattern as established by the timeouts on
acceptors. There are three methods: set_timeout, set_read_timeout, and
set_write_timeout. Each of these sets a point in the future after which
operations will time out.
Timeouts with cloned objects are a little trickier. Each object is viewed as
having its own timeout, unaffected by other objects' timeouts. Additionally,
timeouts do not propagate when a stream is cloned or when a cloned stream has
its timeouts modified.
This commit is just the public interface which will be exposed for timeouts, the
implementation will come in later commits.
Two new methods were added to TcpStream and UnixStream:
fn close_read(&mut self) -> IoResult<()>;
fn close_write(&mut self) -> IoResult<()>;
These two methods map to shutdown()'s behavior (the system call on unix),
closing the reading or writing half of a duplex stream. These methods are
primarily added to allow waking up a pending read in another task. By closing
the reading half of a connection, all pending readers will be woken up and will
return with EndOfFile. The close_write() method was added for symmetry with
close_read(), and I imagine that it will be quite useful at some point.
Implementation-wise, librustuv got the short end of the stick this time. The
native versions just delegate to the shutdown() syscall (easy). The uv versions
can leverage uv_shutdown() for tcp/unix streams, but only for closing the
writing half. Closing the reading half is done through some careful dancing to
wake up a pending reader.
As usual, windows likes to be different from unix. The windows implementation
uses shutdown() for sockets, but shutdown() is not available for named pipes.
Instead, CancelIoEx was used with same fancy synchronization to make sure
everyone knows what's up.
cc #11165
Two new methods were added to TcpStream and UnixStream:
fn close_read(&mut self) -> IoResult<()>;
fn close_write(&mut self) -> IoResult<()>;
These two methods map to shutdown()'s behavior (the system call on unix),
closing the reading or writing half of a duplex stream. These methods are
primarily added to allow waking up a pending read in another task. By closing
the reading half of a connection, all pending readers will be woken up and will
return with EndOfFile. The close_write() method was added for symmetry with
close_read(), and I imagine that it will be quite useful at some point.
Implementation-wise, librustuv got the short end of the stick this time. The
native versions just delegate to the shutdown() syscall (easy). The uv versions
can leverage uv_shutdown() for tcp/unix streams, but only for closing the
writing half. Closing the reading half is done through some careful dancing to
wake up a pending reader.
As usual, windows likes to be different from unix. The windows implementation
uses shutdown() for sockets, but shutdown() is not available for named pipes.
Instead, CancelIoEx was used with same fancy synchronization to make sure
everyone knows what's up.
cc #11165
These implementations must live in libstd right now because the fmt module has
not been migrated yet. This will occur in a later PR.
Just to be clear, there are new extension traits, but they are not necessary
once the std::fmt module has migrated to libcore, which is a planned migration
in the future.
This adds an small of failure to libcore, hamstrung by the fact that std::fmt
hasn't been migrated yet. A few asserts were re-worked to not use std::fmt
features, but these asserts can go back to their original form once std::fmt has
migrated.
The current failure implementation is to just have some symbols exposed by
std::rt::unwind that are linked against by libcore. This is an explicit circular
dependency, unfortunately. This will be officially supported in the future
through compiler support with much nicer failure messages. Additionally, there
are two depended-upon symbols today, but in the future there will only be one
(once std::fmt has migrated).
This moves as much allocation as possible from teh std::str module into
core::str. This includes essentially all non-allocating functionality, mostly
iterators and slicing and such.
This primarily splits the Str trait into only having the as_slice() method,
adding a new StrAllocating trait to std::str which contains the relevant new
allocation methods. This is a breaking change if any of the methods of "trait
Str" were overriden. The old functionality can be restored by implementing both
the Str and StrAllocating traits.
[breaking-change]
for `~str`/`~[]`.
Note that `~self` still remains, since I forgot to add support for
`Box<self>` before the snapshot.
How to update your code:
* Instead of `~EXPR`, you should write `box EXPR`.
* Instead of `~TYPE`, you should write `Box<Type>`.
* Instead of `~PATTERN`, you should write `box PATTERN`.
[breaking-change]
This adds support for connecting to a unix socket with a timeout (a named pipe
on windows), and accepting a connection with a timeout. The goal is to bring
unix pipes/named sockets back in line with TCP support for timeouts.
Similarly to the TCP sockets, all methods are marked #[experimental] due to
uncertainty about the type of the timeout argument.
This internally involved a good bit of refactoring to share as much code as
possible between TCP servers and pipe servers, but the core implementation did
not change drastically as part of this commit.
cc #13523
This update brings a few months of changes, but primarily a fix for the
following situation.
When creating a handle to stdin, libuv used to set the stdin handle to
nonblocking mode. This would end up affect this stdin handle across all
processes that shared it, which mean that stdin become nonblocking for everyone
using the same stdin. On linux, this also affected *stdout* because stdin/stdout
roughly point at the same thing.
This problem became apparent when running the test suite manually on a local
computer. The stdtest suite (running with libgreen) would set stdout to
nonblocking mode (as described above), and then the next test suite would always
fail for a printing failure (because stdout was returning EAGAIN).
This has been fixed upstream, joyent/libuv@342e8c, and this update pulls in this
fix. This also brings us in line with a recently upstreamed libuv patch.
Closes#13336Closes#13355
This adds experimental support for timeouts when accepting sockets through
`TcpAcceptor::accept`. This does not add a separate `accept_timeout` function,
but rather it adds a `set_timeout` function instead. This second function is
intended to be used as a hard deadline after which all accepts will never block
and fail immediately.
This idea was derived from Go's SetDeadline() methods. We do not currently have
a robust time abstraction in the standard library, so I opted to have the
argument be a relative time in millseconds into the future. I believe a more
appropriate argument type is an absolute time, but this concept does not exist
yet (this is also why the function is marked #[experimental]).
The native support is built on select(), similarly to connect_timeout(), and the
green support is based on channel select and a timer.
cc #13523
This adds experimental support for timeouts when accepting sockets through
`TcpAcceptor::accept`. This does not add a separate `accept_timeout` function,
but rather it adds a `set_timeout` function instead. This second function is
intended to be used as a hard deadline after which all accepts will never block
and fail immediately.
This idea was derived from Go's SetDeadline() methods. We do not currently have
a robust time abstraction in the standard library, so I opted to have the
argument be a relative time in millseconds into the future. I believe a more
appropriate argument type is an absolute time, but this concept does not exist
yet (this is also why the function is marked #[experimental]).
The native support is built on select(), similarly to connect_timeout(), and the
green support is based on channel select and a timer.
cc #13523
This alters the borrow checker's requirements on invoking closures from
requiring an immutable borrow to requiring a unique immutable borrow. This means
that it is illegal to invoke a closure through a `&` pointer because there is no
guarantee that is not aliased. This does not mean that a closure is required to
be in a mutable location, but rather a location which can be proven to be
unique (often through a mutable pointer).
For example, the following code is unsound and is no longer allowed:
type Fn<'a> = ||:'a;
fn call(f: |Fn|) {
f(|| {
f(|| {})
});
}
fn main() {
call(|a| {
a();
});
}
There is no replacement for this pattern. For all closures which are stored in
structures, it was previously allowed to invoke the closure through `&self` but
it now requires invocation through `&mut self`.
The standard library has a good number of violations of this new rule, but the
fixes will be separated into multiple breaking change commits.
Closes#12224
As with the previous commits, the Finally trait is primarily implemented for
closures, so the trait was modified from `&self` to `&mut self`. This will
require that any closure variable invoked with `finally` to be stored in a
mutable slot.
[breaking-change]