Commit Graph

298 Commits

Author SHA1 Message Date
Alex Crichton
d1cace17af trans: Upgrade LLVM
This brings some routine upgrades to the bundled LLVM that we're using, the most
notable of which is a bug fix to the way we handle range asserts when loading
the discriminant of an enum. This fix ended up being very similar to f9d4149c
where we basically can't have a range assert when loading a discriminant due to
filling drop, and appropriate flags were added to communicate this to
`trans::adt`.
2016-01-29 16:25:20 -08:00
bors
53c2933d44 Auto merge of #30900 - michaelwoerister:trans_item_collect, r=nikomatsakis
The purpose of the translation item collector is to find all monomorphic instances of functions, methods and statics that need to be translated into LLVM IR in order to compile the current crate.

So far these instances have been discovered lazily during the trans path. For incremental compilation we want to know the set of these instances in advance, and that is what the trans::collect module provides.
In the future, incremental and regular translation will be driven by the collector implemented here.

r? @nikomatsakis
cc @rust-lang/compiler

Translation Item Collection
===========================

This module is responsible for discovering all items that will contribute to
to code generation of the crate. The important part here is that it not only
needs to find syntax-level items (functions, structs, etc) but also all
their monomorphized instantiations. Every non-generic, non-const function
maps to one LLVM artifact. Every generic function can produce
from zero to N artifacts, depending on the sets of type arguments it
is instantiated with.
This also applies to generic items from other crates: A generic definition
in crate X might produce monomorphizations that are compiled into crate Y.
We also have to collect these here.

The following kinds of "translation items" are handled here:

 - Functions
 - Methods
 - Closures
 - Statics
 - Drop glue

The following things also result in LLVM artifacts, but are not collected
here, since we instantiate them locally on demand when needed in a given
codegen unit:

 - Constants
 - Vtables
 - Object Shims

General Algorithm
-----------------
Let's define some terms first:

 - A "translation item" is something that results in a function or global in
   the LLVM IR of a codegen unit. Translation items do not stand on their
   own, they can reference other translation items. For example, if function
   `foo()` calls function `bar()` then the translation item for `foo()`
   references the translation item for function `bar()`. In general, the
   definition for translation item A referencing a translation item B is that
   the LLVM artifact produced for A references the LLVM artifact produced
   for B.

 - Translation items and the references between them for a directed graph,
   where the translation items are the nodes and references form the edges.
   Let's call this graph the "translation item graph".

 - The translation item graph for a program contains all translation items
   that are needed in order to produce the complete LLVM IR of the program.

The purpose of the algorithm implemented in this module is to build the
translation item graph for the current crate. It runs in two phases:

 1. Discover the roots of the graph by traversing the HIR of the crate.
 2. Starting from the roots, find neighboring nodes by inspecting the MIR
    representation of the item corresponding to a given node, until no more
    new nodes are found.

The roots of the translation item graph correspond to the non-generic
syntactic items in the source code. We find them by walking the HIR of the
crate, and whenever we hit upon a function, method, or static item, we
create a translation item consisting of the items DefId and, since we only
consider non-generic items, an empty type-substitution set.

Given a translation item node, we can discover neighbors by inspecting its
MIR. We walk the MIR and any time we hit upon something that signifies a
reference to another translation item, we have found a neighbor. Since the
translation item we are currently at is always monomorphic, we also know the
concrete type arguments of its neighbors, and so all neighbors again will be
monomorphic. The specific forms a reference to a neighboring node can take
in MIR are quite diverse. Here is an overview:

The most obvious form of one translation item referencing another is a
function or method call (represented by a CALL terminator in MIR). But
calls are not the only thing that might introduce a reference between two
function translation items, and as we will see below, they are just a
specialized of the form described next, and consequently will don't get any
special treatment in the algorithm.

A function does not need to actually be called in order to be a neighbor of
another function. It suffices to just take a reference in order to introduce
an edge. Consider the following example:

```rust
fn print_val<T: Display>(x: T) {
    println!("{}", x);
}

fn call_fn(f: &Fn(i32), x: i32) {
    f(x);
}

fn main() {
    let print_i32 = print_val::<i32>;
    call_fn(&print_i32, 0);
}
```
The MIR of none of these functions will contain an explicit call to
`print_val::<i32>`. Nonetheless, in order to translate this program, we need
an instance of this function. Thus, whenever we encounter a function or
method in operand position, we treat it as a neighbor of the current
translation item. Calls are just a special case of that.

In a way, closures are a simple case. Since every closure object needs to be
constructed somewhere, we can reliably discover them by observing
`RValue::Aggregate` expressions with `AggregateKind::Closure`. This is also
true for closures inlined from other crates.

Drop glue translation items are introduced by MIR drop-statements. The
generated translation item will again have drop-glue item neighbors if the
type to be dropped contains nested values that also need to be dropped. It
might also have a function item neighbor for the explicit `Drop::drop`
implementation of its type.

A subtle way of introducing neighbor edges is by casting to a trait object.
Since the resulting fat-pointer contains a reference to a vtable, we need to
instantiate all object-save methods of the trait, as we need to store
pointers to these functions even if they never get called anywhere. This can
be seen as a special case of taking a function reference.

Since `Box` expression have special compiler support, no explicit calls to
`exchange_malloc()` and `exchange_free()` may show up in MIR, even if the
compiler will generate them. We have to observe `Rvalue::Box` expressions
and Box-typed drop-statements for that purpose.

Interaction with Cross-Crate Inlining
-------------------------------------
The binary of a crate will not only contain machine code for the items
defined in the source code of that crate. It will also contain monomorphic
instantiations of any extern generic functions and of functions marked with
The collection algorithm handles this more or less transparently. When
constructing a neighbor node for an item, the algorithm will always call
`inline::get_local_instance()` before proceeding. If no local instance can
be acquired (e.g. for a function that is just linked to) no node is created;
which is exactly what we want, since no machine code should be generated in
the current crate for such an item. On the other hand, if we can
successfully inline the function, we subsequently can just treat it like a
local item, walking it's MIR et cetera.

Eager and Lazy Collection Mode
------------------------------
Translation item collection can be performed in one of two modes:

 - Lazy mode means that items will only be instantiated when actually
   referenced. The goal is to produce the least amount of machine code
   possible.

 - Eager mode is meant to be used in conjunction with incremental compilation
   where a stable set of translation items is more important than a minimal
   one. Thus, eager mode will instantiate drop-glue for every drop-able type
   in the crate, even of no drop call for that type exists (yet). It will
   also instantiate default implementations of trait methods, something that
   otherwise is only done on demand.

Open Issues
-----------
Some things are not yet fully implemented in the current version of this
module.

Since no MIR is constructed yet for initializer expressions of constants and
statics we cannot inspect these properly.

Ideally, no translation item should be generated for const fns unless there
is a call to them that cannot be evaluated at compile time. At the moment
this is not implemented however: a translation item will be produced
regardless of whether it is actually needed or not.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/rust-lang/rust/30900)
<!-- Reviewable:end -->
2016-01-29 03:41:44 +00:00
bors
4b615854f0 Auto merge of #31120 - alexcrichton:attribute-deny-warnings, r=brson
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.

Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
2016-01-26 22:10:10 +00:00
Michael Woerister
862911df9a Implement the translation item collector.
The purpose of the translation item collector is to find all monomorphic instances of functions, methods and statics that need to be translated into LLVM IR in order to compile the current crate.
So far these instances have been discovered lazily during the trans path. For incremental compilation we want to know the set of these instances in advance, and that is what the trans::collect module provides.
In the future, incremental and regular translation will be driven by the collector implemented here.
2016-01-26 10:17:45 -05:00
Alex Crichton
2273b52023 mk: Move from -D warnings to #![deny(warnings)]
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.

Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
2016-01-24 20:35:55 -08:00
Nick Cameron
0ac8915875 The war on abort_if_errors 2016-01-22 08:19:27 +13:00
bors
340e7eb2a7 Auto merge of #31024 - oli-obk:move_checks_out_of_librustc, r=arielb1
-    check_const
-    check_static_recursion
-    check_loop
-    check_rvalues

r? @arielb1
2016-01-21 15:21:09 +00:00
Oliver Schneider
c124deca7b move more checks out of librustc 2016-01-21 10:52:37 +01:00
bors
34b4e66736 Auto merge of #29520 - retep998:staticlib-naming-fiasco, r=alexcrichton
I'm not sure if this was the best way to go about it, but it seems to work.

Fixes https://github.com/rust-lang/rust/issues/29508

r? @alexcrichton
2016-01-21 09:02:48 +00:00
Vadim Petrochenkov
2084c2c33a Rename Def's variants and don't reexport them 2016-01-20 22:31:10 +03:00
Vadim Petrochenkov
ceaaa1bc33 Refactor definitions of ADTs in rustc::middle::def 2016-01-20 21:50:57 +03:00
Peter Atashian
06c66d6ca2 Change name when outputting staticlibs on Windows
libfoo.a -> foo.lib
In order to not cause conflicts, changes the DLL import library name
foo.lib -> foo.dll.lib

Fixes https://github.com/rust-lang/rust/issues/29508

Because this changes output filenames this is a [breaking-change]

Signed-off-by: Peter Atashian <retep998@gmail.com>
2016-01-16 12:34:54 -05:00
Vadim Petrochenkov
ccb4b35897 Preserve struct/variant kinds in metadata
Add tests for use of empty structs in cross-crate scenarios
2016-01-15 19:57:53 +03:00
Michael Woerister
c8a547a638 Also store MIR of closures in crate metadata. 2016-01-08 09:45:26 -05:00
Jeffrey Seyfried
76021d84b3 Refactor away extension traits RegionEscape and HasTypeFlags 2016-01-07 00:42:12 +00:00
Niko Matsakis
d48f48f61f Refactor compiler to make use of dep-tracking-maps. Also, in cases where
we were using interior mutability (RefCells, TyIvar), add some reads/writes.
2016-01-05 21:05:51 -05:00
bors
4744472fe0 Auto merge of #30264 - GuillaumeGomez:patch-5, r=Manishearth
r? @Manishearth

Also: should I merged both commits? Not sure if it's really useful to keep the first one.
2016-01-02 16:56:15 +00:00
Guillaume Gomez
55955f5a45 Add E0463 error explanation 2016-01-02 02:39:45 +01:00
Simonas Kazlauskas
23d24ff667 Rollup merge of #30565 - michaelwoerister:opaque_encoder, r=brson
This PR changes the `emit_opaque` and `read_opaque` methods in the RBML library to use a space-efficient binary encoder that does not emit any tags and uses the LEB128 variable-length integer format for all numbers it emits.

The space savings are nice, albeit a bit underwhelming, especially for dynamic libraries where metadata is already compressed.

| RLIBs        |  NEW   |   OLD     |
|--------------|--------|-----------|
|libstd        | 8.8 MB |  10.5 MB  |
|libcore       |15.6 MB |   19.7 MB |
|libcollections| 3.7 MB |    4.8 MB |
|librustc      |34.0 MB |   37.8 MB |
|libsyntax     |28.3 MB |   32.1 MB |

| SOs           |     NEW   |    OLD |
|---------------|-----------|--------|
| libstd        |  4.8 MB   | 5.1 MB |
| librustc      |  8.6 MB   | 9.2 MB |
| libsyntax     |  7.8 MB   | 8.4 MB |

At least this should make up for the size increase caused recently by also storing MIR in crate metadata.

Can this be a breaking change for anyone?
cc @rust-lang/compiler
2015-12-31 18:52:20 +02:00
bors
5892852168 Auto merge of #30585 - Ms2ger:ExplicitSelfCategory, r=brson 2015-12-31 01:12:38 +00:00
Nick Cameron
04d972906d Rebasing and review comments 2015-12-30 14:54:36 +13:00
Nick Cameron
95dc7efad0 use structured errors 2015-12-30 14:27:59 +13:00
Corey Richardson
992feab697
Add a hint when given --extern with an indeterminate type
@ubsan brought up this relatively poor error message. This adds a
help message hinting when the problem actually is, and how to fix
it.
2015-12-29 00:25:37 -05:00
Michael Woerister
fa2a7411e4 Use a more efficient encoding for opaque data in RBML. 2015-12-28 12:15:44 -05:00
Ms2ger
b2c370370e Rename ExplicitSelfCategory's variants and stop re-exporting them. 2015-12-28 12:52:43 +01:00
Ariel Ben-Yehuda
efc45758fd rewrite the method-receiver matching code
the old code was *so terrible*.
2015-12-28 00:52:37 +02:00
Michael Woerister
4c4195f269 Fix def paths creation for items inlined from external crates.
Avoid duplicating the last element of the def path which led to paths like "std::slice::into_vec::into_vec".
2015-12-22 10:27:59 -05:00
Alex Crichton
cd1848a1a6 Register new snapshots
Lots of cruft to remove!
2015-12-21 09:26:21 -08:00
Manish Goregaokar
c2902965cb Rollup merge of #30384 - nrc:diagnostics, r=@nikomatsakis
Should make it possible to add JSON or HTML errors. Also tidies up a lot.
2015-12-18 16:47:37 +05:30
bors
6734dccc31 Auto merge of #30325 - jseyfried:fixes_30078, r=nrc
This fixes a bug in which unused imports can get wrongly marked as used when checking for unused qualifications in `resolve_path` (issue #30078), and it removes unused imports that were previously undetected because of the bug.
2015-12-17 18:21:25 +00:00
Jeffrey Seyfried
8364a6feef Remove unused imports 2015-12-17 05:43:27 +00:00
bors
9687a8a969 Auto merge of #30354 - petrochenkov:defuse, r=sanxiyn
A relic of some old resolution algorithm?
2015-12-17 01:22:53 +00:00
bors
4af4278814 Auto merge of #30341 - pnkfelix:call-site-scope, r=nikomatsakis
Ensure borrows of fn/closure params do not outlive invocations.

Does this by adding a new CallSiteScope to the region (or rather code extent) hierarchy, which outlives even the ParameterScope (which in turn outlives the DestructionScope of a fn/closure's body).

Fix #29793

r? @nikomatsakis
2015-12-16 22:53:19 +00:00
Nick Cameron
6309b0f5bb move error handling from libsyntax/diagnostics.rs to libsyntax/errors/*
Also split out emitters into their own module.
2015-12-17 09:35:50 +13:00
Vadim Petrochenkov
0cc69f0ea3 rustc: Remove def::DefUse 2015-12-16 18:19:11 +03:00
Manish Goregaokar
ee24bddfc5 Rollup merge of #30320 - nrc:err-names, r=@nikomatsakis
We can now handle name resolution errors and get past type checking (if we're a bit lucky). This is the first step towards doing code completion for partial programs (we need error recovery in the parser and early access to save-analysis).
2015-12-16 17:46:29 +05:30
Felix S. Klock II
c00574848b Ensure borrows of fn/closure params do not outlive invocations.
resolve_lifetime.rs: Switch from BlockScope to FnScope in ScopeChain
construction. Lifetimes introduced by a fn signature are scoped to the
call-site for that fn. (Note `add_scope_and_walk_fn` must only add
FnScope for the walk of body, *not* of the fn signature.)

region.rs: Introduce new CodeExtentData::CallSiteScope variant. Use
CodeExtentData as the cx.parent, rather than just a NodeId.  Change
DestructionScopeData to CallSiteScopeData.

regionck.rs: Thread call_site_scope via Rcx; constrain fn return
values.

(update; incorporated review feedback from niko.)
2015-12-15 15:18:40 +01:00
Vadim Petrochenkov
e3ed7b0501 Implement #[deprecated] attribute (RFC 1270) 2015-12-12 19:39:37 +03:00
Nick Cameron
18b4fe0e3e Make name resolution errors non-fatal 2015-12-11 21:00:15 +13:00
Michael Woerister
5addc31adb Make MIR encodable and store it in crate metadata. 2015-12-10 16:59:31 -05:00
bors
eebf6743d8 Auto merge of #30140 - michaelwoerister:tls-encoding, r=nikomatsakis
With this commit, metadata encoding and decoding can make use of thread-local encoding and decoding contexts. These allow implementers of `serialize::Encodable` and `Decodable` to access information and
datastructures that would otherwise not be available to them. For example, we can automatically translate def-id and span information during decoding because the decoding context knows which crate the data is decoded from. Or it allows to make `ty::Ty` decodable because the context has access to the `ty::ctxt` that is needed for creating `ty::Ty` instances.

Some notes:
- `tls::with_encoding_context()` and `tls::with_decoding_context()` (as opposed to their unsafe versions) try to prevent the TLS data getting out-of-sync by making sure that the encoder/decoder passed in is actually the same as the one stored in the context. This should prevent accidentally reading from the wrong decoder.
- There are no real tests in this PR. I had a unit tests for some of the core aspects of the TLS implementation but it was kind of brittle, a lot of code for mocking `ty::ctxt`, `crate_metadata`, etc and did actually test not so much. The code will soon be tested by the first incremental compilation auto-tests that rely on MIR being properly serialized. However, if people think that some tests should be added before this can land, I'll try to provide some that make sense.

r? @nikomatsakis
2015-12-09 15:10:37 +00:00
Michael Woerister
f65823e39c Add scoped thread-local encoding and decoding contexts to cstore.
With this commit, metadata encoding and decoding can make use of
thread-local encoding and decoding contexts. These allow implementers
of serialize::Encodable and Decodable to access information and
datastructures that would otherwise not be available to them. For
example, we can automatically translate def-id and span information
during decoding because the decoding context knows which crate the
data is decoded from. Or it allows to make ty::Ty decodable because
the context has access to the ty::ctxt that is needed for creating
ty::Ty instances.
2015-12-09 09:47:32 -05:00
bors
acf4e0be22 Auto merge of #30087 - petrochenkov:indi, r=nrc
I've measured the time/memory consumption before and after - the difference is lost in statistical noise, so it's mostly a code simplification.
Sizes of `enum`s are not affected.

r? @nrc

I wonder if AST/HIR visitors could run faster if `P`s are systematically removed (except for cases where they control `enum` sizes). Theoretically they should.
Remaining unnecessary `P`s can't be easily removed because many folders accept `P<X>`s as arguments, but these folders can be converted to accept `X`s instead without loss of efficiency.
When I have a mood for some mindless refactoring again, I'll probably try to convert the folders, remove remaining `P`s and measure again.
2015-12-07 22:28:45 +00:00
Vadim Petrochenkov
ca88e9c536 Remove some unnecessary indirection from HIR structures 2015-12-07 17:17:41 +03:00
Alex Crichton
464cdff102 std: Stabilize APIs for the 1.6 release
This commit is the standard API stabilization commit for the 1.6 release cycle.
The list of issues and APIs below have all been through their cycle-long FCP and
the libs team decisions are listed below

Stabilized APIs

* `Read::read_exact`
* `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`)
* libcore -- this was a bit of a nuanced stabilization, the crate itself is now
  marked as `#[stable]` and the methods appearing via traits for primitives like
  `char` and `str` are now also marked as stable. Note that the extension traits
  themeselves are marked as unstable as they're imported via the prelude. The
  `try!` macro was also moved from the standard library into libcore to have the
  same interface. Otherwise the functions all have copied stability from the
  standard library now.
* The `#![no_std]` attribute
* `fs::DirBuilder`
* `fs::DirBuilder::new`
* `fs::DirBuilder::recursive`
* `fs::DirBuilder::create`
* `os::unix::fs::DirBuilderExt`
* `os::unix::fs::DirBuilderExt::mode`
* `vec::Drain`
* `vec::Vec::drain`
* `string::Drain`
* `string::String::drain`
* `vec_deque::Drain`
* `vec_deque::VecDeque::drain`
* `collections::hash_map::Drain`
* `collections::hash_map::HashMap::drain`
* `collections::hash_set::Drain`
* `collections::hash_set::HashSet::drain`
* `collections::binary_heap::Drain`
* `collections::binary_heap::BinaryHeap::drain`
* `Vec::extend_from_slice` (renamed from `push_all`)
* `Mutex::get_mut`
* `Mutex::into_inner`
* `RwLock::get_mut`
* `RwLock::into_inner`
* `Iterator::min_by_key` (renamed from `min_by`)
* `Iterator::max_by_key` (renamed from `max_by`)

Deprecated APIs

* `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`)
* `OsString::from_bytes`
* `OsStr::to_cstring`
* `OsStr::to_bytes`
* `fs::walk_dir` and `fs::WalkDir`
* `path::Components::peek`
* `slice::bytes::MutableByteVector`
* `slice::bytes::copy_memory`
* `Vec::push_all` (renamed to `extend_from_slice`)
* `Duration::span`
* `IpAddr`
* `SocketAddr::ip`
* `Read::tee`
* `io::Tee`
* `Write::broadcast`
* `io::Broadcast`
* `Iterator::min_by` (renamed to `min_by_key`)
* `Iterator::max_by` (renamed to `max_by_key`)
* `net::lookup_addr`

New APIs (still unstable)

* `<[T]>::sort_by_key` (added to mirror `min_by_key`)

Closes #27585
Closes #27704
Closes #27707
Closes #27710
Closes #27711
Closes #27727
Closes #27740
Closes #27744
Closes #27799
Closes #27801
cc #27801 (doesn't close as `Chars` is still unstable)
Closes #28968
2015-12-05 15:09:44 -08:00
mitaa
af1ad419e1 Use the extern item-path for documentation links
The local item-path includes the local crates path to the extern crate
declaration which breaks cross-crate rustdoc links if the extern crate
is not linked into the crate root or renamed via `extern foo as bar`.
2015-12-03 23:11:19 +01:00
Ariel Ben-Yehuda
4190dce3a7 fix tidy 2015-11-26 18:22:40 +02:00
Ariel Ben-Yehuda
0a8bb4c509 split the metadata code into rustc_metadata
tests & rustdoc still broken
2015-11-26 18:22:40 +02:00