This is needed so that the FFI works as expected on platforms that don't
flatten aggregates the way the AMD64 ABI does, especially for `#[repr(C)]`.
This moves more of `type_of` into `trans::adt`, because the type might
or might not be an LLVM struct.
Closes#10308.
This moves the locking/waiting methods to returning an RAII struct instead of
relying on closures. Additionally, this changes the methods to all take
'&mut self' to discourage recursive locking. The new method to block is to call
`wait` on the returned RAII structure instead of calling it on the lock itself
(this enforces that the lock is held).
At the same time, this improves the Mutex interface a bit by allowing
destruction of non-initialized members and by allowing construction of an empty
mutex (nothing initialized inside).
This is a behavioral difference in libuv between different platforms in
different situations. It turns out that libuv on windows will immediately
allocate a buffer instead of waiting for data to be ready. What this implies is
that we must have our custom data set on the handle before we call
uv_read_start.
I wish I knew of a way to test this, but this relies to being on the windows
platform *and* reading from a true TTY handle which only happens when this is
actually attached to a terminal. I have manually verified this works.
Closes#10645
Currently, the parser doesn't give any context when it finds an unclosed
delimiter and it's not EOF. Report the most recent unclosed delimiter, to help
the user along.
Closes#10636
This is both useful for performance (otherwise logging is unbuffered), but also
useful for correctness. Because when a task is destroyed we can't block the task
waiting for the logger to close, loggers are opened with a 'CloseAsynchronously'
specification. This causes libuv do defer the call to close() until the next
turn of the event loop.
If you spin in a tight loop around printing, you never yield control back to the
libuv event loop, meaning that you simply enqueue a large number of close
requests but nothing is actually closed. This queue ends up never getting
closed, meaning that if you keep trying to create handles one will eventually
fail, which the runtime will attempt to print the failure, causing mass
destruction.
Caching will provide better performance as well as prevent creation of too many
handles.
Closes#10626
This is needed so that the FFI works as expected on platforms that don't
flatten aggregates the way the AMD64 ABI does, especially for `#[repr(C)]`.
This moves more of `type_of` into `trans::adt`, because the type might
or might not be an LLVM struct.
This is a behavioral difference in libuv between different platforms in
different situations. It turns out that libuv on windows will immediately
allocate a buffer instead of waiting for data to be ready. What this implies is
that we must have our custom data set on the handle before we call
uv_read_start.
I wish I knew of a way to test this, but this relies to being on the windows
platform *and* reading from a true TTY handle which only happens when this is
actually attached to a terminal. I have manually verified this works.
Closes#10645
The reasons for doing this are:
* The model on which linked failure is based is inherently complex
* The implementation is also very complex, and there are few remaining who
fully understand the implementation
* There are existing race conditions in the core context switching function of
the scheduler, and possibly others.
* It's unclear whether this model of linked failure maps well to a 1:1 threading
model
Linked failure is often a desired aspect of tasks, but we would like to take a
much more conservative approach in re-implementing linked failure if at all.
Closes#8674Closes#8318Closes#8863
This is both useful for performance (otherwise logging is unbuffered), but also
useful for correctness. Because when a task is destroyed we can't block the task
waiting for the logger to close, loggers are opened with a 'CloseAsynchronously'
specification. This causes libuv do defer the call to close() until the next
turn of the event loop.
If you spin in a tight loop around printing, you never yield control back to the
libuv event loop, meaning that you simply enqueue a large number of close
requests but nothing is actually closed. This queue ends up never getting
closed, meaning that if you keep trying to create handles one will eventually
fail, which the runtime will attempt to print the failure, causing mass
destruction.
Caching will provide better performance as well as prevent creation of too many
handles.
Closes#10626
The reasons for doing this are:
* The model on which linked failure is based is inherently complex
* The implementation is also very complex, and there are few remaining who
fully understand the implementation
* There are existing race conditions in the core context switching function of
the scheduler, and possibly others.
* It's unclear whether this model of linked failure maps well to a 1:1 threading
model
Linked failure is often a desired aspect of tasks, but we would like to take a
much more conservative approach in re-implementing linked failure if at all.
Closes#8674Closes#8318Closes#8863
Make TrieMap/TrieSet's find_mut check the key for external nodes.
Without this find_mut sometimes returns a reference to another key when
querying for a non-present key.
Currently, the parser doesn't give any context when it finds an unclosed
delimiter and it's not EOF. Report the most recent unclosed delimiter, to help
the user along.
Closes#10636
Make TrieMap/TrieSet's find_mut check the key for external nodes.
Without this find_mut sometimes returns a reference to another key when
querying for a non-present key.
Issue #8763 is about improving a particular error message.
* added case & better error message for "impl trait for module"
* added compile-fail test trait-impl-for-module.rs
* updated copyright dates
* revised compile-fail test trait-or-new-type-instead
(the error message for the modified test is still unclear, but that's a different bug https://github.com/mozilla/rust/issues/8767)
* added case & better error message for "impl trait for module"
* used better way to print the module
* switched from //error-pattern to //~ ERROR
* added compile-fail test trait-impl-for-module.rs
* revised compile-fail test trait-or-new-type-instead
(the error message for the modified test is still unclear, but that's a different bug)
* added FIXME to trait-or-new-type-instead
With these changes I was able to cross compile for windows from a linux box. (Using the mingw-w64 package on Debian Testing).
Fixed a bug where the `target_family` cfg would be wrong when targeting something with a different value than the host. (i.e windows -> unix or unix -> windows).
Also, removed `LIBUV_FLAGS` in `mk/rt.mk` because of the redundancy between it and `CFG_GCCISH_CFLAGS_(target)`.
After this we can create a snapshot and migrate to mingw64 instead of mingw32.
This is based off of @blake2-ppc's work on #9429. That PR bitrotted and I haven't been able to contact the original author so I decided to take up the cause.
Overview
======
`Mut` encapsulates a mutable, non-nullable slot. The `Cell` type is currently used to do this, but `Cell` is much more commonly used as a workaround for the inability to move values into non-once functions. `Mut` provides a more robust API.
`Mut` duplicates the semantics of borrowed pointers with enforcement at runtime instead of compile time.
```rust
let x = Mut::new(0);
{
// make some immutable borrows
let p = x.borrow();
let y = *p.get() + 10;
// multiple immutable borrows are allowed simultaneously
let p2 = x.borrow();
// this would throw a runtime failure
// let p_mut = x.borrow_mut();
}
// now we can mutably borrow
let p = x.borrow_mut();
*p.get() = 10;
```
`borrow` returns a `Ref` type and `borrow_mut` returns a `RefMut` type, both of which are simple smart pointer types with a single method, `get`, which returns a reference to the wrapped data.
This also allows `RcMut<T>` to be deleted, as it can be replaced with `Rc<Mut<T>>`.
Changes
======
I've done things a little bit differently than the original proposal.
* I've added `try_borrow` and `try_borrow_mut` methods that return `Option<Ref<T>>` and `Option<RefMut<T>>` respectively instead of failing on a borrow check failure. I'm not totally sure when that'd be useful, but I don't see any reason to not put them in and @cmr requested them.
* `ReadPtr` and `WritePtr` have been renamed to `Ref` and `RefMut` respectively, as `Ref` is to `ref foo` and `RefMut` is to `ref mut foo` as `Mut` is to `mut foo`.
* `get` on `MutRef` now takes `&self` instead of `&mut self` for consistency with `&mut`. As @alexcrichton pointed, out this violates soundness by allowing aliasing `&mut` references.
* `Cell` is being left as is. It solves a different problem than `Mut` is designed to solve.
* There are no longer methods implemented for `Mut<Option<T>>`. Since `Cell` isn't going away, there's less of a need for these, and I didn't feel like they provided a huge benefit, especially as that kind of `impl` is very uncommon in the standard library.
Open Questions
============
* `Cell` should now be used exclusively for movement into closures. Should this be enforced by reducing its API to `new` and `take`? It seems like this use case will be completely going away once the transition to `proc` and co. finishes.
* Should there be `try_map` and `try_map_mut` methods along with `map` and `map_mut`?
I cannot tell whether the original comment was unsure about the
arithmetic calculations, or if it was unsure about the assumptions
being made about the alignment of the current allocation pointer.
The arithmetic calculation looks fine to me, though. This technique
is documented e.g. in Henry Warren's "Hacker's Delight" (section 3-1).
(I am sure one can find it elsewhere too, its not an obscure
property.)
I added a test case which does not compile today, and required changes on
privacy's side of things to get right. Additionally, this moves a good bit of
logic which did not belong in reachability into privacy.
All of reachability should solely be responsible for determining what the
reachable surface area of a crate is given the exported surface area (where the
exported surface area is that which is usable by external crates).
Privacy will now correctly figure out what's exported by deeply looking
through reexports. Previously if a module were reexported under another name,
nothing in the module would actually get exported in the executable. I also
consolidated the phases of privacy to be clearer about what's an input to what.
The privacy checking pass no longer uses the notion of an "all public" path, and
the embargo visitor is no longer an input to the checking pass.
Currently the embargo visitor is built as a saturating analysis because it's
unknown what portions of the AST are going to get re-exported.
This also cracks down on exported methods from impl blocks and trait blocks. If you implement a private trait, none of the symbols are exported, and if you have an impl for a private type none of the symbols are exported either. On the other hand, if you implement a public trait for a private type, the symbols are still exported. I'm unclear on whether this last part is correct, but librustc will fail to link unless it's in place.
I added a test case which does not compile today, and required changes on
privacy's side of things to get right. Additionally, this moves a good bit of
logic which did not belong in reachability into privacy.
All of reachability should solely be responsible for determining what the
reachable surface area of a crate is given the exported surface area (where the
exported surface area is that which is usable by external crates).
Privacy will now correctly figure out what's exported by deeply looking
through reexports. Previously if a module were reexported under another name,
nothing in the module would actually get exported in the executable. I also
consolidated the phases of privacy to be clearer about what's an input to what.
The privacy checking pass no longer uses the notion of an "all public" path, and
the embargo visitor is no longer an input to the checking pass.
Currently the embargo visitor is built as a saturating analysis because it's
unknown what portions of the AST are going to get re-exported.
I cannot tell whether the original comment was unsure about the
arithmetic calculations, or if it was unsure about the assumptions
being made about the alignment of the current allocation pointer.
The arithmetic calculation looks fine to me, though. This technique
is documented e.g. in Henry Warren's "Hacker's Delight" (section 3-1).
(I am sure one can find it elsewhere too, its not an obscure
property.)
New benchmark tests in vec.rs:
`push`, `starts_with_same_vector`, `starts_with_single_element`,
`starts_with_diff_one_element_end`, `ends_with_same_vector`,
`ends_with_single_element`, `ends_with_diff_one_element_beginning` and
`contains_last_element`
This isn't very useful yet, but it does replace most functionality of `@T`. The `Mut<T>` type will make it unnecessary to have a `GcMut<T>` so I haven't included one. Obviously it doesn't work for trait objects but that needs to be figured out for `Rc<T>` too.
This was needed to access UEFI boot services in my new Boot2Rust experiment.
I also realized that Rust functions declared as extern always use the C calling convention regardless of how they were declared, so this pull request fixes that as well.
This implements a fair amount of the unimpl() functionality in io::native
relating to filesystem operations. I've also modified all io::fs tests to run in
both a native and uv environment (so everything is actually tested).
There are a few bits of remaining functionality which I was unable to get
working:
* truncate on windows
* change_file_times on windows
* lstat on windows
I think that change_file_times may just need a better interface, but the other
two have large implementations in libuv which I didn't want to tackle trying to
copy. I found a `chsize` function to work for truncate on windows, but it
doesn't quite seem to be working out.
This implements a fair amount of the unimpl() functionality in io::native
relating to filesystem operations. I've also modified all io::fs tests to run in
both a native and uv environment (so everything is actually tested).
There are a two bits of remaining functionality which I was unable to get
working:
* change_file_times on windows
* lstat on windows
I think that change_file_times may just need a better interface, but lstat has a
large implementation in libuv which I didn't want to tackle trying to copy.
There are issues with reading stdin when it is actually attached to a pipe, but
I have run into no problems in writing to stdout/stderr when they are attached
to pipes.
ToStr, Encodable and Decodable are not marked as such, since they're
already expensive, and lead to large methods, so inlining will bloat the
metadata & the binaries.
This means that something like
#[deriving(Eq)]
struct A { x: int }
creates an instance like
#[doc = "Automatically derived."]
impl ::std::cmp::Eq for A {
#[inline]
fn eq(&self, __arg_0: &A) -> ::bool {
match *__arg_0 {
A{x: ref __self_1_0} =>
match *self {
A{x: ref __self_0_0} => true && __self_0_0.eq(__self_1_0)
}
}
}
#[inline]
fn ne(&self, __arg_0: &A) -> ::bool {
match *__arg_0 {
A{x: ref __self_1_0} =>
match *self {
A{x: ref __self_0_0} => false || __self_0_0.ne(__self_1_0)
}
}
}
}
(The change being the `#[inline]` attributes.)
Provide `Closed01` and `Open01` that generate directly from the
closed/open intervals from 0 to 1, in contrast to the plain impls for
f32 and f64 which generate the half-open [0,1).
Fixes#7755.
Explicitly have the only C++ portion of the runtime be one file with exception
handling. All other runtime files must now live in C and be fully defined in C.
This mutex is built on top of pthreads for unix and the related windows apis on
windows. This is a straight port of the lock_and_signal type from C++ to rust.
Almost all operations on the type are unsafe, and it's definitely not
recommended for general use.
Closes#9105
This replaces `*` with `..` in enums, `_` with `..` in structs, and `.._` with `..` in vectors. It adds obsolete syntax warnings for the old forms but doesn't turn them on yet because we need a snapshot.
#5830
There are issues with reading stdin when it is actually attached to a pipe, but
I have run into no problems in writing to stdout/stderr when they are attached
to pipes.
ToStr, Encodable and Decodable are not marked as such, since they're
already expensive, and lead to large methods, so inlining will bloat the
metadata & the binaries.
This means that something like
#[deriving(Eq)]
struct A { x: int }
creates an instance like
#[doc = "Automatically derived."]
impl ::std::cmp::Eq for A {
#[inline]
fn eq(&self, __arg_0: &A) -> ::bool {
match *__arg_0 {
A{x: ref __self_1_0} =>
match *self {
A{x: ref __self_0_0} => true && __self_0_0.eq(__self_1_0)
}
}
}
#[inline]
fn ne(&self, __arg_0: &A) -> ::bool {
match *__arg_0 {
A{x: ref __self_1_0} =>
match *self {
A{x: ref __self_0_0} => false || __self_0_0.ne(__self_1_0)
}
}
}
}
(The change being the `#[inline]` attributes.)
This PR improves the single-stepping experience for if-expression (no more jumping into the *else* branch before entering the *then* branch, no more jumping to the end of the *else* branch after finishing the *then* branch). Unfortunately I don't know of a straight-forward way of writing automated tests for this. Suggestions welcome!
Changes:
* default value when no args
* license
* removed libc printing
* use extra::bigint instead of handmade gmp binding
The drawback is that it's 2 order of magnitude slower, the good news is that there is a good bench for extra::bigint.
If a function is marked as external, then it's likely desired for use with some
native library, so we're not really accomplishing a whole lot by internalizing
all of these symbols.
If a function is marked as external, then it's likely desired for use with some
native library, so we're not really accomplishing a whole lot by internalizing
all of these symbols.
Provide `Closed01` and `Open01` that generate directly from the
closed/open intervals from 0 to 1, in contrast to the plain impls for
f32 and f64 which generate the half-open [0,1).
Fixes#7755.
This commit fixes issue #10468.
It propagate optimization level from PkgSrc to compile_crate as a rustc::driver::session::OptLevel enum.
The 'opt' argument to compile_crate was previously hardcoded as boolean false, such that calls to session::options would always result in the session::No flag being used.
* moved `extern` inside module
* changed `extern "stdcall"` to `extern "system"`
* changed `cfg(target_os="win32")` to `cfg(windows)`
* only run on Windows && x86, (not x86_64)
* updated copyright dates
There was a syntax error because the `extern "stdcall"` was outside the module instead of inside it.
* moved `extern` inside module
* change `extern "stdcall"` to `extern "system"`
* change `cfg(target_os="win32")` to `cfg(windows)`
* updated copyright dates
* changed log(error, ...) => info!(....)
* added `pub` keyword to kernel32 functions
Changes:
* add licence;
* remove usage of libc and unsafe;
* use BufferedWriter to improve performance;
* use a DummyWriter to cancel binary output in test.
If any of the digits was one past the maximum (e.g. 10**9 for base 10),
then this wasn't detected correctly and so the length of the digit was
one more than expected, causing a very large allocation.
Fixes#10522.
Fixes#10288.
Changes:
* add licence;
* remove usage of libc and unsafe;
* use BufferedWriter to improve performance;
* use a DummyWriter to cancel binary output in test.
These commits create a `Buffer` trait in the `io` module which represents an I/O reader which is internally buffered. This abstraction is used to reasonably implement `read_line` and `read_until` along with at least an ok implementation of `read_char` (although I certainly haven't benchmarked `read_char`).
If any of the digits was one past the maximum (e.g. 10**9 for base 10),
then this wasn't detected correctly and so the length of the digit was
one more than expected, causing a very large allocation.
Fixes#10522.
Fixes#10288.
This implementation of the meteor contest implements:
- insertion check with bit trick;
- pregenetation of every feasible placement of the pieces on the
board;
- filtering of placement that implies unfeasible board
- central symetry breaking
related to #2776
I've started working on this issue and pushed a small commit, which adds a range check for integer literals in `middle::const_eval` (no `uint` at the moment)
At the moment, this patch is just a proof of concept, I'm not sure if there is a better function for the checks in `middle::const_eval`. This patch does not check for overflows after constant folding, eg:
let x: i8 = 99 + 99;
Bare functions are another example of a scalar but non-numeric
type (like char) that should be handled separately in casts.
This disallows expressions like `0 as extern "Rust" fn() -> int;`.
It might be advantageous to allow casts between bare functions
and raw pointers in unsafe code in the future, to pass function
pointers between Rust and C.
Closes#8728
This implementation of the meteor contest implements:
- insertion check with bit trick;
- pregenetation of every feasible placement of the pieces on the
board;
- filtering of placement that implies unfeasible board
- central symetry breaking
Rename {struct-update,fsu}-moves-and-copies, since win32
failed to run the test since UAC prevents any executable whose
name contaning "update". (#10452)
Some tests related to #9205 are expected to fail on gcc 4.8,
so they are marked as `xfail-win32` instead of `xfail-fast`.
Some tests using `extra::tempfile` fail on win32 due to #10462.
Mark them as `xfail-win32`.
This commit re-organizes the io::native module slightly in order to have a
working implementation of rtio::IoFactory which uses native implementations. The
goal is to seamlessly multiplex among libuv/native implementations wherever
necessary.
Right now most of the native I/O is unimplemented, but we have existing bindings
for file descriptors and processes which have been hooked up. What this means is
that you can now invoke println!() from libstd with no local task, no local
scheduler, and even without libuv.
There's still plenty of work to do on the native I/O factory, but this is the
first steps into making it an official portion of the standard library. I don't
expect anyone to reach into io::native directly, but rather only std::io
primitives will be used. Each std::io interface seamlessly falls back onto the
native I/O implementation if the local scheduler doesn't have a libuv one
(hurray trait ojects!)
This commit re-organizes the io::native module slightly in order to have a
working implementation of rtio::IoFactory which uses native implementations. The
goal is to seamlessly multiplex among libuv/native implementations wherever
necessary.
Right now most of the native I/O is unimplemented, but we have existing bindings
for file descriptors and processes which have been hooked up. What this means is
that you can now invoke println!() from libstd with no local task, no local
scheduler, and even without libuv.
There's still plenty of work to do on the native I/O factory, but this is the
first steps into making it an official portion of the standard library. I don't
expect anyone to reach into io::native directly, but rather only std::io
primitives will be used. Each std::io interface seamlessly falls back onto the
native I/O implementation if the local scheduler doesn't have a libuv one
(hurray trait ojects!)
This test was failing periodically on windows and other platforms, and in
debugging the issue locally I've found that the previous test was failing
at the assertion `ns0 <= ns1`. Upon inspecting the values, the two numbers were
very close to one another, but off by a little bit.
I believe that this is because `precise_time_s` goes from `u64` -> `f64` and
then we go again back to `u64` for the assertion. This conversion is a lossy one
that's not always guaranteed to succeed, so instead I've changed the test to
only compare against u64 instances.
I implemented BufWriter. I realize the use of conditions are on their way out for IO, but it does raise a condition if a write will not fit in the buffer for now.
I also replaced the seek code for MemWriter. It was adding the offset as a uint, which is unsound for negative offsets. It only happened to work because unsigned addition performs the same operation with two's complement, and sizeof(uint) <= sizeof(i64) so there was no (lack of) sign extension. I replaced this with computing an offset as an i64 and clamping to zero. I don't expect anyone will have use BufWriter with a byte buffer greater than 2^63 bytes any time soon.
@alexcrichton
Closes#10433
This trait is meant to abstract whether a reader is actually implemented with an
underlying buffer. For all readers which are implemented as such, we can
efficiently implement things like read_char, read_line, read_until, etc. There
are two required methods for managing the internal buffer, and otherwise
read_line and friends can all become default methods.
Closes#10334
Filled in the implementations of Writer and Seek for BufWriter. It
raises the io_error condition if a write cannot fit in the buffer.
The Seek implementation for MemWriter, which was incorrectly using
unsigned arithmatic to add signed offsets, has also been replaced.
Now the privacy pass returns enough information that other passes do not need to duplicate the visibility rules, and the missing_doc implementation is more consistent with other lint checks.
Previously, the `exported_items` set created by the privacy pass was
incomplete. Specifically, it did not include items that had been defined
at a private path but then `pub use`d at a public path. This commit
finds all crate exports during the privacy pass. Consequently, some code
in the reachable pass and in rustdoc is no longer necessary. This commit
then removes the separate `MissingDocLintVisitor` lint pass, opting to
check missing_doc lint in the same pass as the other lint checkers using
the visibility result computed by the privacy pass.
Fixes#9777.