Adjust the handling of `#[inline]` items so that they get translated into every
compilation unit that uses them. This is necessary to preserve the semantics
of `#[inline(always)]`.
Crate-local `#[inline]` functions and statics are blindly translated into every
compilation unit. Cross-crate inlined items and monomorphizations of
`#[inline]` functions are translated the first time a reference is seen in each
compilation unit. When using multiple compilation units, inlined items are
given `available_externally` linkage whenever possible to avoid duplicating
object code.
Add a post-processing pass to `trans` that converts symbols from external to
internal when possible. Translation with multiple compilation units initially
makes most symbols external, since it is not clear when translating a
definition whether that symbol will need to be accessed from another
compilation unit. This final pass internalizes symbols that are not reachable
from other crates and not referenced from other compilation units, so that LLVM
can perform more aggressive optimizations on those symbols.
Use a shared lookup table of previously-translated monomorphizations/glue
functions to avoid translating those functions in every compilation unit where
they're used. Instead, the function will be translated in whichever
compilation unit uses it first, and the remaining compilation units will link
against that original definition.
Rotate between compilation units while translating. The "worker threads"
commit added support for multiple compilation units, but only translated into
one, leaving the rest empty. With this commit, `trans` rotates between various
compilation units while translating, using a simple stragtegy: upon entering a
module, switch to translating into whichever compilation unit currently
contains the fewest LLVM instructions.
Most of the actual changes here involve getting symbol linkage right, so that
items translated into different compilation units will link together properly
at the end.
When inlining an item from another crate, use the original symbol from that
crate's metadata instead of generating a new symbol using the `ast::NodeId` of
the inlined copy. This requires exporting symbols in the crate metadata in a
few additional cases. Having predictable symbols for inlined items will be
useful later to avoid generating duplicate object code for inlined items.
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
Break up `CrateContext` into `SharedCrateContext` and `LocalCrateContext`. The
local piece corresponds to a single compilation unit, and contains all
LLVM-related components. (LLVM data structures are tied to a specific
`LLVMContext`, and we will need separate `LLVMContext`s to safely run
multithreaded optimization.) The shared piece contains data structures that
need to be shared across all compilation units, such as the `ty::ctxt` and some
tables related to crate metadata.
They were only correct in the simplest case. Some of the optimisations
are certainly possible but should be introduced carefully and only
when the whole pattern codegen infrastructure is in a better shape.
Fixes#16648.
closes#16800
r? @nikomatsakis - I'm not 100% sure this is the right approach, it is kind of ad-hoc. The trouble is we don't have any intrinsic notion of which types are sized and which are not, we only have the Sized bound, so I have nothing to validate the Sized bound against.
For example `let _x: &Trait = &*(box Foo as Box<Trait>);`. There was a bug where no cleanup would be scheduled by the deref.
No test because cleanup-auto-borrow-obj.rs is a test for this once we remove trait cross-borrowing (done on another branch).
Not sure if this is addressing the root cause or just patching up a symptom. Also not sure if I should be adding a diagnostic code for this.
Fixes#16750Fixes#15812
They were only correct in the simplest case. Some of the optimisations
are certainly possible but should be introduced carefully and only
when the whole pattern codegen infrastructure is in a better shape.
Fixes#16648.
Different Identifiers and Names can have identical textual representations, but different internal representations, due to the macro hygiene machinery (syntax contexts and gensyms). This provides a way to see these internals by compiling with `--pretty expanded,hygiene`.
This is useful for debugging & hacking on macros (e.g. diagnosing https://github.com/rust-lang/rust/issues/15750/https://github.com/rust-lang/rust/issues/15962 likely would've been faster with this functionality).
E.g.
```rust
#![feature(macro_rules)]
// minimal junk
#![no_std]
macro_rules! foo {
($x: ident) => { y + $x }
}
fn bar() {
foo!(x)
}
```
```rust
#![feature(macro_rules)]
// minimal junk
#![no_std]
fn bar /* 61#0 */() { y /* 60#2 */ + x /* 58#3 */ }
```
Fixes#12643
> Say!
> I like labelled breaks/continues!
I will use them with a `for` loop.
And I will use with a `loop` loop.
Say! I will use them ANYWHERE!
… _even_ in a `while` loop.
Because they're now supported there.
`--pretty expanded,hygiene` is helpful with debugging macro issues,
since two identifiers/names can be textually the same, but different
internally (resulting in weird "undefined variable" errors).
This adds support for lint groups to the compiler. Lint groups are a way of
grouping a number of lints together under one name. For example, this also
defines a default lint for naming conventions, named `bad_style`. Writing
`#[allow(bad_style)]` is equivalent to writing
`#[allow(non_camel_case_types, non_snake_case, non_uppercase_statics)]`. These
lint groups can also be defined as a compiler plugin using the new
`Registry::register_lint_group` method.
This also adds two built-in lint groups, `bad_style` and `unused`. The contents
of these groups can be seen by running `rustc -W help`.
This unifies the `non_snake_case_functions` and `uppercase_variables` lints
into one lint, `non_snake_case`. It also now checks for non-snake-case modules.
This also extends the non-camel-case types lint to check type parameters, and
merges the `non_uppercase_pattern_statics` lint into the
`non_uppercase_statics` lint.
Because the `uppercase_variables` lint is now part of the `non_snake_case`
lint, all non-snake-case variables that start with lowercase characters (such
as `fooBar`) will now trigger the `non_snake_case` lint.
New code should be updated to use the new `non_snake_case` lint instead of the
previous `non_snake_case_functions` and `uppercase_variables` lints. All use of
the `non_uppercase_pattern_statics` should be replaced with the
`non_uppercase_statics` lint. Any code that previously contained non-snake-case
module or variable names should be updated to use snake case names or disable
the `non_snake_case` lint. Any code with non-camel-case type parameters should
be changed to use camel case or disable the `non_camel_case_types` lint.
[breaking-change]
The inference scheme proposed in <http://smallcultfollowing.com/babysteps/blog/2014/07/09/an-experimental-new-type-inference-scheme-for-rust/>.
This is theoretically a [breaking-change]. It is possible that you may encounter type checking errors, particularly related to closures or functions with higher-ranked lifetimes or object types. Adding more explicit type annotations should help the problem. However, I have not been able to make an example that *actually* successfully compiles with the older scheme and fails with the newer scheme.
f? @pcwalton, @pnkfelix
This squashes the
> `for` loop expression has type `[type error]` which does not implement
> the `Iterator` trait
message that one received when writing `for ... in x` where was
previously found to have a type error.
Fixes#16042.