Add checks for null bytes in the value strings for the export_name and link_section attributes, reporting an error if any are found, before calling with_c_str on them.
Fixes#16478
This breaks code like:
struct Foo {
...
}
pub fn make_foo() -> Foo {
...
}
Change this code to:
pub struct Foo { // note `pub`
...
}
pub fn make_foo() -> Foo {
...
}
The `visible_private_types` lint has been removed, since it is now an
error to attempt to expose a private type in a public API. In its place
a `#[feature(visible_private_types)]` gate has been added.
Closes#16463.
RFC #48.
[breaking-change]
- Don't attempt to autoderef `!`. The `Deref`/`DerefMut` trait lookup would generate a bunch of unhelpful error spew.
- Don't allow explicit deref of `!`, since later passes just ICE. This closes issue #17373
- Don't allow explicit index of `!`, since later passes just ICE. There does not seem to be an issue associated with this
Later compiler passes are not prepared to deal with deref of
`ty_bot` and will generate various ICEs, so disallow it outright for now.
Closes issue #17373
Change to resolve and update compiler and libs for uses.
[breaking-change]
Enum variants are now in both the value and type namespaces. This means that
if you have a variant with the same name as a type in scope in a module, you
will get a name clash and thus an error. The solution is to either rename the
type or the variant.
Part of issue #16640. I am leaving this issue open to handle parsing of
higher-rank lifetimes in traits.
This change breaks code that used unboxed closures:
* Instead of `F:|&: int| -> int`, write `F:Fn(int) -> int`.
* Instead of `F:|&mut: int| -> int`, write `F:FnMut(int) -> int`.
* Instead of `F:|: int| -> int`, write `F:FnOnce(int) -> int`.
[breaking-change]
The implementation essentially desugars during type collection and AST
type conversion time into the parameter scheme we have now. Only fully
qualified names--e.g. `<T as Foo>::Bar`--are supported.
Recursive items are currently detected in the `check_const` pass which runs after type checking. This means a recursive static item used as an array length will cause type checking to blow the stack. This PR separates the recursion check out into a separate pass which is run before type checking.
Closes issue #17252
r? @nick29581
As per [RFC 52](https://github.com/rust-lang/rfcs/blob/master/active/0052-ownership-variants.md), use `_mut` suffixes to mark mutable variants, and `into_iter` for moving iterators. Additional details and motivation in the RFC.
Note that the iterator *type* names are not changed by this RFC; those are awaiting a separate RFC for standardization.
Closes#13660Closes#16810
[breaking-change]
lifetime bounds. This doesn't really cause any difficulties, because
we already had to accommodate the fact that multiple implicit bounds
could accumulate. Object types still require precisely one lifetime
bound. This is a pre-step towards generalized where clauses (once you
have lifetime bounds in where clauses, it is harder to restrict them
to exactly one).
This patch does not make many functional changes, but does a lot of restructuring towards the goals of #5527. This is the biggest patch, basically, that should enable most of the other patches in a relatively straightforward way.
Major changes:
- Do not track impls through trans, instead recompute as needed.
- Isolate trait matching code into its own module, carefully structure to distinguish various phases (selection vs confirmation vs fulfillment)
- Consider where clauses in their more general form
- Integrate checking of builtin bounds into the trait matching process, rather than doing it separately in kind.rs (important for opt-in builtin bounds)
What is not included:
- Where clauses are still not generalized. This should be a straightforward follow-up patch.
- Caching. I did not include much caching. I have plans for various kinds of caching we can do. Should be straightforward. Preliminary perf measurements suggested that this branch keeps compilation times roughly what they are.
- Method resolution. The initial algorithm I proposed for #5527 does not work as well as I hoped. I have a revised plan which is much more similar to what we do today.
- Deref vs deref-mut. The initial fix I had worked great for autoderef, but not for explicit deref.
- Permitting blanket impls to overlap with specific impls. Initial plan to consider all nested obligations before considering an impl to match caused many compilation errors. We have a revised plan but it is not implemented here, should be a relatively straightforward extension.
- Unify the "well-formedness" checking that typeck was already doing with what
was taking place in kind.
- Move requirements that things be sized into typeck.
- I left the checking on upvars in kind, though I think it should eventually be
refactored into regionck (which would perhaps be renamed).
This reflects a general plan to convert typeck so that it registers
obligations or other pending things for conditions it cannot check
eventually. This makes it easier to identify all the conditions that
apply to an AST expression, but can also influence inference in somec
cases (e.g., `Send` implies `'static`, so I already had to promote a lot
of the checking that `kind.rs` was doing into typeck, this branch just
continues the process).
I would like to map this information back to AST nodes, so that we can print remarks with spans, and so that remarks can be enabled on a per-function basis. Unfortunately, doing this would require a lot more code restructuring — for example, we currently throw away the AST map and lots of other information before LLVM optimizations run. So for the time being, we print the remarks with debug location strings from LLVM. There's a warning if you use `-C remark` without `--debuginfo`.
Fixes#17116.
This new pass is run before type checking so that recursive items
are detected beforehand. This prevents going into an infinite
recursion during type checking when a recursive item is used in
an array type.
As a bonus, use `span_err` instead of `span_fatal` so multiple
errors can be reported.
Closes issue #17252
`Box<[T]>` is created by allocating `Box<[T, ..n]>` and coercing it so
this code path is never used. It's also broken because it clamps the
capacity of the memory allocations to 4 elements and that's incompatible
with sized deallocation. This dates back to when `~[T]` was a growable
vector type implemented as:
*{ { tydesc, ref_count, prev, next }, { length, capacity, data[] } }
Since even empty vectors had to allocate, it started off the capacity of
all vectors at 4 as a heuristic. It's not possible to grow `Box<[T]>`
and there is no need for a memory allocation when it's empty, so it
would be a terrible heuristic today even if it worked.
type they provide an implementation for.
This breaks code like:
mod foo {
struct Foo { ... }
}
impl foo::Foo {
...
}
Change this code to:
mod foo {
struct Foo { ... }
impl Foo {
...
}
}
Additionally, if you used the I/O path extension methods `stat`,
`lstat`, `exists`, `is_file`, or `is_dir`, note that these methods have
been moved to the the `std::io::fs::PathExtensions` trait. This breaks
code like:
fn is_it_there() -> bool {
Path::new("/foo/bar/baz").exists()
}
Change this code to:
use std::io::fs::PathExtensions;
fn is_it_there() -> bool {
Path::new("/foo/bar/baz").exists()
}
Closes#17059.
RFC #155.
[breaking-change]
This PR creates a new lint : ``unused_extern_crate``, which do pretty much the same thing as ``unused_import``, but for ``extern crate`` statements. It is related to feature request #10385.
I adapted the code tracking used imports so that it tracks extern crates usage as well. This was mainly trial and error and while I believe all cases are covered, there might be some code I added that is useless (long compile times didn't give me the opportunity to check this in detail).
Also, I removed some unused ``extern crate`` statements from the libs, that where spotted by this new lint.
`Box<[T]>` is created by allocating `Box<[T, ..n]>` and coercing it so
this code path is never used. It's also broken because it clamps the
capacity of the memory allocations to 4 elements and that's incompatible
with sized deallocation. This dates back to when `~[T]` was a growable
vector type implemented as:
*{ { tydesc, ref_count, prev, next }, { length, capacity, data[] } }
Since even empty vectors had to allocate, it started off the capacity of
all vectors at 4 as a heuristic. It's not possible to grow `Box<[T]>`
and there is no need for a memory allocation when it's empty, so it
would be a terrible heuristic today even if it worked.
Avoid ever constructing cyclic types in the first place, rather than detecting them in resolve. This simplifies logic elsewhere in the compiler, in particular on the trait reform branch.
r? @pnkfelix or @pcwalton
cc #5527
The pointer in the slice must not be null, because enum representations
make that assumption. The `exchange_malloc` function returns a non-null
sentinel for the zero size case, and it must not be passed to the
`exchange_free` lang item.
Since the length is always equal to the true capacity, a branch on the
length is enough for most types. Slices of zero size types are
statically special cased to never attempt deallocation. This is the same
implementation as `Vec<T>`.
Closes#14395
This allows code to access the fields of tuples and tuple structs:
let x = (1i, 2i);
assert_eq!(x.1, 2);
struct Point(int, int);
let origin = Point(0, 0);
assert_eq!(origin.0, 0);
assert_eq!(origin.1, 0);
The pointer in the slice must not be null, because enum representations
make that assumption. The `exchange_malloc` function returns a non-null
sentinel for the zero size case, and it must not be passed to the
`exchange_free` lang item.
Since the length is always equal to the true capacity, a branch on the
length is enough for most types. Slices of zero size types are
statically special cased to never attempt deallocation. This is the same
implementation as `Vec<T>`.
Closes#14395
instead of prefix `..`.
This breaks code that looked like:
match foo {
[ first, ..middle, last ] => { ... }
}
Change this code to:
match foo {
[ first, middle.., last ] => { ... }
}
RFC #55.
Closes#16967.
[breaking-change]
itself.
This breaks code like:
for &x in my_vector.iter() {
my_vector[2] = "wibble";
...
}
Change this code to not invalidate iterators. For example:
for i in range(0, my_vector.len()) {
my_vector[2] = "wibble";
...
}
The `for-loop-does-not-borrow-iterators` test for #8372 was incorrect
and has been removed.
Closes#16820.
[breaking-change]
A match in callee.rs was recognizing some foreign fns as named tuple constructors. A reproducible test case for this is nearly impossible since it depends on the way NodeIds happen to be assigned in different crates.
Fixes#15913
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).