This commit let librustc automatically pickup LDFLAGS dependencies
inherited from LLVM, which may otherwise result in undefined
references to external symbols under certain linking environment.
A symptom of this issue is eg. a failure when trying to link against
librustc (due to unresolved ffi_*i symbols), while using a system-wide
LLVM.
Signed-off-by: Luca Bruno <lucab@debian.org>
Macro definitions are just their raw source code, and so should be
highlighted where possible. Also, $ident non-terminal substitutions are
special, and so are worthy of a little special treatment.
When the metadata format changes, old libraries often cause librustc to abort
when reading their metadata. This should all change with the introduction of SVH
markers, but the loader for crates should gracefully handle libraries without
SVH markers still.
This commit adds support for tripping fewer assertions when loading libraries by
using maybe_get_doc when initially parsing metadata. It's still possible for
some libraries to fall through the cracks, but this should deal with a fairly
large number of them up front.
When the metadata format changes, old libraries often cause librustc to abort
when reading their metadata. This should all change with the introduction of SVH
markers, but the loader for crates should gracefully handle libraries without
SVH markers still.
This commit adds support for tripping fewer assertions when loading libraries by
using maybe_get_doc when initially parsing metadata. It's still possible for
some libraries to fall through the cracks, but this should deal with a fairly
large number of them up front.
Macro definitions are just their raw source code, and so should be
highlighted where possible. Also, $ident non-terminal substitutions are
special, and so are worth of a little special treatment.
Now that we can call `flush()` in destructors, I think that it's appropriate for stdout/stderr to return buffered writers by default.
This doesn't enable certain functionality like a buffered stdin does, but it's what you want 90% of the time for performance reasons.
Similarly to #12422 which made stdin buffered by default, this commit makes the
output streams also buffered by default. Now that buffered writers will flush
their contents when they are dropped, I don't believe that there's no reason why
the output shouldn't be buffered by default, which is what you want in 90% of
cases.
As with stdin, there are new stdout_raw() and stderr_raw() functions to get
unbuffered streams to stdout/stderr.
It's still not entirely clear what should happen if there was an error when
flushing, but I'm deferring that decision to #12628. I believe that it's crucial
for the usefulness of buffered writers to be able to flush on drop. It's just
too easy to forget to flush them in small one-off use cases.
cc #12628
We weren't passing the node id for the enum and hence it couldn't retrieve the field types for the struct variant we were trying to destructure.
Fixes#11577.
From my comment on #11450:
The reason for the ICE is because for operators `rustc` does a little bit of magic. Notice that while you implement the `Mul` trait for some type `&T` (i.e a reference to some T), you can simply do `Vec2 {..} * 2.0f32`. That is, `2.0f32` is `f32` and not `&f32`. This works because `rustc` will automatically take a reference. So what's happening is that with `foo * T`, the compiler is expecting the `mul` method to take some `&U` and then it can compare to make sure `T == U` (or more specifically that `T` coerces to `U`). But in this case, the argument of the `mul` method is not a reference and hence the "no ref" error.
I don't think we should ICE in this case since we do catch the mismatched trait/impl method and hence provide a better error message that way.
Fixes#11450
Formatting via reflection has been a little questionable for some time now, and
it's a little unfortunate that one of the standard macros will silently use
reflection when you weren't expecting it. This adds small bits of code bloat to
libraries, as well as not always being necessary. In light of this information,
this commit switches assert_eq!() to using {} in the error message instead of
{:?}.
In updating existing code, there were a few error cases that I encountered:
* It's impossible to define Show for [T, ..N]. I think DST will alleviate this
because we can define Show for [T].
* A few types here and there just needed a #[deriving(Show)]
* Type parameters needed a Show bound, I often moved this to `assert!(a == b)`
* `Path` doesn't implement `Show`, so assert_eq!() cannot be used on two paths.
I don't think this is much of a regression though because {:?} on paths looks
awful (it's a byte array).
Concretely speaking, this shaved 10K off a 656K binary. Not a lot, but sometime
significant for smaller binaries.
Formatting via reflection has been a little questionable for some time now, and
it's a little unfortunate that one of the standard macros will silently use
reflection when you weren't expecting it. This adds small bits of code bloat to
libraries, as well as not always being necessary. In light of this information,
this commit switches assert_eq!() to using {} in the error message instead of
{:?}.
In updating existing code, there were a few error cases that I encountered:
* It's impossible to define Show for [T, ..N]. I think DST will alleviate this
because we can define Show for [T].
* A few types here and there just needed a #[deriving(Show)]
* Type parameters needed a Show bound, I often moved this to `assert!(a == b)`
* `Path` doesn't implement `Show`, so assert_eq!() cannot be used on two paths.
I don't think this is much of a regression though because {:?} on paths looks
awful (it's a byte array).
Concretely speaking, this shaved 10K off a 656K binary. Not a lot, but sometime
significant for smaller binaries.
This helps prevent interleaving of error messages when running rustdoc tests.
This has an interesting bit of shuffling with I/O handles, but other than that
this is just using the APIs laid out in the previous commit.
Closes#12623
I've been playing around with code size when linking to libstd recently, and these were some findings I found that really helped code size. I started out by eliminating all I/O implementations from libnative and instead just return an unimplemented error.
In doing so, a `fn main() {}` executable was ~378K before this patch, and about 170K after the patch. These size wins are all pretty minor, but they all seemed pretty reasonable to me. With native I/O not stubbed out, this takes the size of an LTO executable from 675K to 400K.
This function is a tiny wrapper that LLVM doesn't want to inline, and it ends up
causing more bloat than necessary. The bloat is pretty small, but it's a win of
at least 7k for small executables, and I imagine that the number goes up as
there are more calls to fail!().
This removes all usage of Poly in format strings from libstd. This doesn't
prevent more future strings from coming in, but it at least removes the ones for
now.
Most of these are unnecessary because we're only looking at static strings. This
also moves to Vec in a few places instead of ~[T].
This didn't end up getting much of a code size win (update_log_settings is the
third largest function in the executables I'm looking at), but this seems like a
generally nice improvement regardless.
This lowers the #[allow(missing_doc)] directive into some of the lower modules
which are less mature. Most I/O modules now require comprehensive documentation.
This commit alters the diagnostic emission machinery to be focused around a
Writer for emitting errors. This allows it to not hard-code emission of errors
to stderr (useful for other applications).
These hashes are used to detect changes to upstream crates and generate errors which mention that crates possibly need recompilation.
More details can be found in the respective commit messages below. This change is also accompanied with a much needed refactoring of some of the crate loading code to focus more on crate ids instead of name/version pairs.
Closes#12601
This lowers the #[allow(missing_doc)] directive into some of the lower modules
which are less mature. Most I/O modules now require comprehensive documentation.
Previously, format!("{a}{b}", a=foo(), b=bar()) has foo() and bar() run in a
nondeterminisc order. This is clearly a non-desirable property, so this commit
uses iteration over a list instead of iteration over a hash map to provide
deterministic code generation of these format arguments.
This new SVH is used to uniquely identify all crates as a snapshot in time of
their ABI/API/publicly reachable state. This current calculation is just a hash
of the entire crate's AST. This is obviously incorrect, but it is currently the
reality for today.
This change threads through the new Svh structure which originates from crate
dependencies. The concept of crate id hash is preserved to provide efficient
matching on filenames for crate loading. The inspected hash once crate metadata
is opened has been changed to use the new Svh.
The goal of this hash is to identify when upstream crates have changed but
downstream crates have not been recompiled. This will prevent the def-id drift
problem where upstream crates were recompiled, thereby changing their metadata,
but downstream crates were not recompiled.
In the future this hash can be expanded to exclude contents of the AST like doc
comments, but limitations in the compiler prevent this change from being made at
this time.
Closes#10207
The previous code passed around a {name,version} pair everywhere, but this is
better expressed as a CrateId. This patch changes these paths to store and pass
around crate ids instead of these pairs of name/version. This also prepares the
code to change the type of hash that is stored in crates.
This is a ubiquitous type in concurrent code, and the assertions are causing
significant code bloat for simple operations such as reading the pointer
(injecting a failure point, etc).
I am testing executable sizes with no I/O implementations (everything stubbed
out to return nothing), and this took the size of a libnative executable from
328K to 207K (37% reduction in size), so I think that this is one assertion
that's well worth configuring off for now.
These are types that are in exported type signatures, but are not
exported themselves, e.g.
struct Foo { ... }
pub fn bar() -> Foo { ... }
will warn about the Foo.
Such types are not listed in documentation, and cannot be named outside
the crate in which they are declared, which is very user-unfriendly.
cc #10573.
There's a lot of these types in the compiler libraries, and a few of the
older or private stdlib ones. Some types are obviously meant to be
public, others not so much.
These are types that are in exported type signatures, but are not
exported themselves, e.g.
struct Foo { ... }
pub fn bar() -> Foo { ... }
will warn about the Foo.
Such types are not listed in documentation, and cannot be named outside
the crate in which they are declared, which is very user-unfriendly.
cc #10573