`Times::times` was always a second-class loop because it did not support the `break` and `continue` operations. Its playful appeal (which I liked) was then lost after `do` was disabled for closures. It's time to let this one go.
`Times::times` was always a second-class loop because it did not support the `break` and `continue` operations. Its playful appeal was then lost after `do` was disabled for closures. It's time to let this one go.
I found awkward to have `MutableCloneableVector` and `CloneableIterator` on the one hand, and `CopyableVector` etc. on the other hand.
The concerned traits are:
* `CopyableVector` --> `CloneableVector`
* `OwnedCopyableVector` --> `OwnedCloneableVector`
* `ImmutableCopyableVector` --> `ImmutableCloneableVector`
* `CopyableTuple` --> `CloneableTuple`
The general consensus is that we want to move away from conditions for I/O, and I propose a two-step plan for doing so:
1. Warn about unused `Result` types. When all of I/O returns `Result`, it will require you inspect the return value for an error *only if* you have a result you want to look at. By default, for things like `write` returning `Result<(), Error>`, these will all go silently ignored. This lint will prevent blind ignorance of these return values, letting you know that there's something you should do about them.
2. Implement a `try!` macro:
```
macro_rules! try( ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) )
```
With these two tools combined, I feel that we get almost all the benefits of conditions. The first step (the lint) is a sanity check that you're not ignoring return values at callsites. The second step is to provide a convenience method of returning early out of a sequence of computations. After thinking about this for awhile, I don't think that we need the so-called "do-notation" in the compiler itself because I think it's just *too* specialized. Additionally, the `try!` macro is super lightweight, easy to understand, and works almost everywhere. As soon as you want to do something more fancy, my answer is "use match".
Basically, with these two tools in action, I would be comfortable removing conditions. What do others think about this strategy?
----
This PR specifically implements the `unused_result` lint. I actually added two lints, `unused_result` and `unused_must_use`, and the first commit has the rationale for why `unused_result` is turned off by default.
In two ways:
- for a plain `fail!(a)` we make the generic part of `begin_unwind` as small as possible (makes `fn main() { fail!() }` compile 2-3x faster, due to less monomorphisation bloat)
- for `fail!("format {}", "string")`, we avoid touching the generics completely by doing the formatting in a specialised function, which (with optimisations) saves a function call at the call-site of `fail!`. (This one has significantly less benefit than the first.)
This ends up saving a single `call` instruction in the optimised code,
but saves a few hundred lines of non-optimised IR for `fn main() {
fail!("foo {}", "bar"); }` (comparing against the minimal generic
baseline from the parent commit).
This splits the vast majority of the code path taken by
`fail!()` (`begin_unwind`) into a separate non-generic inline(never)
function, so that uses of `fail!()` only monomorphise a small amount of
code, reducing code bloat and making very small crates compile faster.
These are either returned from public functions, and really should
appear in the documentation, but don't since they're private, or are
implementation details that are currently public.
These are either returned from public functions, and really should
appear in the documentation, but don't since they're private, or are
implementation details that are currently public.
The following are renamed:
* `min_value` => `MIN`
* `max_value` => `MAX`
* `bits` => `BITS`
* `bytes` => `BYTES`
All tests pass, except for `run-pass/phase-syntax-link-does-resolve.rs`. I doubt that failure is related, though.
Fixes#10010.
The race here happened when a port had its deschedule in select() canceled, but
the other chan had already been dropped. This meant that the DISCONNECTED case
was hit in abort_selection, but the to_wake cell hadn't been emptied yet (this
was done after aborting), causing an assert in abort_selection to trip.
To fix this, the to_wake cell is just emptied before abort_selection is called
(we know that we're the owner of it already).
They all have to go into a single module at the moment unfortunately.
Ideally, the logging macros would live in std::logging, condition! would
live in std::condition, format! in std::fmt, etc. However, this
introduces cyclic dependencies between those modules and the macros they
use which the current expansion system can't deal with. We may be able
to get around this by changing the expansion phase to a two-pass system
but that's for a later PR.
Closes#2247
cc #11763
The race here happened when a port had its deschedule in select() canceled, but
the other chan had already been dropped. This meant that the DISCONNECTED case
was hit in abort_selection, but the to_wake cell hadn't been emptied yet (this
was done after aborting), causing an assert in abort_selection to trip.
To fix this, the to_wake cell is just emptied before abort_selection is called
(we know that we're the owner of it already).
They all have to go into a single module at the moment unfortunately.
Ideally, the logging macros would live in std::logging, condition! would
live in std::condition, format! in std::fmt, etc. However, this
introduces cyclic dependencies between those modules and the macros they
use which the current expansion system can't deal with. We may be able
to get around this by changing the expansion phase to a two-pass system
but that's for a later PR.
Closes#2247
cc #11763
Before this commit, rustc looked in `dirname $0`/../lib for libraries
but that doesn't work when rustc is invoked through a symlink.
This commit makes rustc look in `dirname $(readlink $0)`/../lib, i.e.
it first canonicalizes the symlink before walking up the directory tree.
Fixes#3632.
Renamed the invert() function in iter.rs to flip().
Also renamed the Invert<T> type to Flip<T>.
Some related code comments changed. Documentation that I could find has
been updated, and all the instances I could locate where the
function/type were called have been updated as well.
This is just an initial implementation and does not yet fully replace `~[T]`. A generic initialization syntax for containers is missing, and the slice functionality needs to be reworked to make auto-slicing unnecessary.
Traits for supporting indexing properly are also required. This also needs to be fixed to make ring buffers as easy to use as vectors.
The tests and documentation for `~[T]` can be ported over to this type when it is removed. I don't really expect DST to happen for vectors as having both `~[T]` and `Vec<T>` is overcomplicated and changing the slice representation to 3 words is not at all appealing. Unlike with traits, it's possible (and easy) to implement `RcSlice<T>` and `GcSlice<T>` without compiler help.