This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes#552
Previously, `//// foo` and `/*** foo ***/` were accepted as doc comments. This
changes that, so that only `/// foo` and `/** foo ***/` are accepted. This
confuses many newcomers and it seems weird.
Also update the manual for these changes, and modernify the EBNF for comments.
Closes#10638
### Rationale
There is no reason to support more than 2³² nodes or names at this moment, as compiling something that big (even without considering the quadratic space usage of some analysis passes) would take at least **64GB**.
Meanwhile, some can't (or barely can) compile rustc because it requires almost **1.5GB**.
### Potential problems
Can someone confirm this doesn't affect metadata (de)serialization? I can't tell myself, I know nothing about it.
### Results
Some structures have a size reduction of 25% to 50%: [before](https://gist.github.com/luqmana/3a82a51fa9c86d9191fa) - [after](https://gist.github.com/eddyb/5a75f8973d3d8018afd3).
Sadly, there isn't a massive change in the memory used for compiling stage2 librustc (it doesn't go over **1.4GB** as [before](http://huonw.github.io/isrustfastyet/mem/), but I can barely see the difference).
However, my own testcase (previously peaking at **1.6GB** in typeck) shows a reduction of **200**-**400MB**.
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
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 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.
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.)
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.)
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.
These two attributes are no longer useful now that Rust has decided to leave
segmented stacks behind. It is assumed that the rust task's stack is always
large enough to make an FFI call (due to the stack being very large).
There's always the case of stack overflow, however, to consider. This does not
change the behavior of stack overflow in Rust. This is still normally triggered
by the __morestack function and aborts the whole process.
C stack overflow will continue to corrupt the stack, however (as it did before
this commit as well). The future improvement of a guard page at the end of every
rust stack is still unimplemented and is intended to be the mechanism through
which we attempt to detect C stack overflow.
Closes#8822Closes#10155