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.)
Non-exhaustive change list:
* `self` is now present in argument lists (modulo type-checking code I don't trust myself to refactor)
* methods have the same calling convention as bare functions (including the self argument)
* the env param is gone from all bare functions (and methods), only used by closures and `proc`s
* bare functions can only be coerced to closures and `proc`s if they are statically resolved, as they now require creating a wrapper specific to that function, to avoid indirect wrappers (equivalent to `impl<..Args, Ret> Fn<..Args, Ret> for fn(..Args) -> Ret`) that might not be optimizable by LLVM and don't work for `proc`s
* refactored some `trans::closure` code, leading to the removal of `trans::glue::make_free_glue` and `ty_opaque_closure_ptr`
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).
I'd forgotten to update them when I changed this a while ago; it now displays error messages linked to the struct/variant field, rather than the `#[deriving(Trait)]` line, for all traits.
This also adds a very large number of autogenerated tests. I can easily remove/tone down that commit if necessary.
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.
This makes error messages about (e.g.) `#[deriving(Clone)] struct Foo {
x: Type }` point at `x: Type` rather than `Clone` in the header (while
still referring to the `#[deriving(Clone)]` in the expansion info).
It was decided a long, long time ago that libextra should not exist, but rather its modules should be split out into smaller independent libraries maintained outside of the compiler itself. The theory was to use `rustpkg` to manage dependencies in order to move everything out of the compiler, but maintain an ease of usability.
Sadly, the work on `rustpkg` isn't making progress as quickly as expected, but the need for dissolving libextra is becoming more and more pressing. Because of this, we've thought that a good interim solution would be to simply package more libraries with the rust distribution itself. Instead of dissolving libextra into libraries outside of the mozilla/rust repo, we can dissolve libraries into the mozilla/rust repo for now.
Work on this has been excruciatingly painful in the past because the makefiles are completely opaque to all but a few. Adding a new library involved adding about 100 lines spread out across 8 files (incredibly error prone). The first commit of this pull request targets this pain point. It does not rewrite the build system, but rather refactors large portions of it. Afterwards, adding a new library is as simple as modifying 2 lines (easy, right?). The build system automatically keeps track of dependencies between crates (rust *and* native), promotes binaries between stages, tracks dependencies of installed tools, etc, etc.
With this newfound buildsystem power, I chose the `extra::flate` module as the first candidate for removal from libextra. While a small module, this module is relative complex in that is has a C dependency and the compiler requires it (messing with the dependency graph a bit). Albeit I modified more than 2 lines of makefiles to accomodate libflate (the native dependency required 2 extra lines of modifications), but the removal process was easy to do and straightforward.
---
Testing-wise, I've cross-compiled, run tests, built some docs, installed, uninstalled, etc. I'm still working out a few kinks, and I'm sure that there's gonna be built system issues after this, but it should be working well for basic use!
cc #8784
This is hopefully the beginning of the long-awaited dissolution of libextra.
Using the newly created build infrastructure for building libraries, I decided
to move the first module out of libextra.
While not being a particularly meaty module in and of itself, the flate module
is required by rustc and additionally has a native C dependency. I was able to
very easily split out the C dependency from rustrt, update librustc, and
magically everything gets installed to the right locations and built
automatically.
This is meant to be a proof-of-concept commit to how easy it is to remove
modules from libextra now. I didn't put any effort into modernizing the
interface of libflate or updating it other than to remove the one glob import it
had.
See #11522, but the idea is for private structs to have private fields by default, whereas public structs will continue to have public fields by default.
This was the original intention of the privacy of structs, and it was
erroneously implemented before. A pub struct will now have default-pub fields,
and a non-pub struct will have default-priv fields. This essentially brings
struct fields in line with enum variants in terms of inheriting visibility.
As usual, extraneous modifiers to visibility are disallowed depend on the case
that you're dealing with.
Closes#11522
Before this patch, if you wanted to add a crate to the build system you had to
change about 100 lines across 8 separate makefiles. This is highly error prone
and opaque to all but a few. This refactoring is targeted at consolidating this
effort so adding a new crate adds one line in one file in a way that everyone
can understand it.
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.
Now that procedural macros can be implemented outside of the compiler,
it's more important to have a reasonable API to work with. Here are the
basic changes:
* Rename SyntaxExpanderTTTrait to MacroExpander, SyntaxExpanderTT to
BasicMacroExpander, etc. I think "procedural macro" is the right
term for these now, right? The other option would be SynExtExpander
or something like that.
* Stop passing the SyntaxContext to extensions. This was only ever used
by macro_rules, which doesn't even use it anymore. I can't think of
a context in which an external extension would need it, and removal
allows the API to be significantly simpler - no more
SyntaxExpanderTTItemExpanderWithoutContext wrappers to worry about.
Now that procedural macros can be implemented outside of the compiler,
it's more important to have a reasonable API to work with. Here are the
basic changes:
* Rename SyntaxExpanderTTTrait to MacroExpander, SyntaxExpanderTT to
BasicMacroExpander, etc. I think "procedural macro" is the right
term for these now, right? The other option would be SynExtExpander
or something like that.
* Stop passing the SyntaxContext to extensions. This was only ever used
by macro_rules, which doesn't even use it anymore. I can't think of
a context in which an external extension would need it, and removal
allows the API to be significantly simpler - no more
SyntaxExpanderTTItemExpanderWithoutContext wrappers to worry about.
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).