Monomorphize's normalization results in a 2% decrease in non-optimized
code size for libstd, so there's a negligible cost to removing it. This
also fixes several visit glue bugs because normalize wasn't considering
the differences in visit glue between types.
Closes#8720
This PR contains some code cleanup and the fix for issue #8670.
~~I am not sure about issue #8442 (could not reproduce it). @jdm, could check after this is merged and possibly close the issue then?~~ (closed now)
Some interesting facts: With this commit, it should be possible to compile libstd with `-Zdebug-info` (it does not work yet with `-Zextra-debug-info` but we are getting there). Switching debug info on increases the compile time for libstd by about 2 seconds.
@catamorphism I get one failing test in rustpkg:
`package_script_with_default_build` says: `task <unnamed> failed at 'Couldn't copy file', /home/mw/rust/src/librustpkg/tests.rs:689`
Would you have any idea what that is about? Seems be something wrong on my machine...
Cheers,
Michael
Fixes#8670
This resolves issue #908.
Notable changes:
- On Windows, LLVM integrated assembler emits bad stack unwind tables when segmented stacks are enabled. However, unwind info directives in the assembly output are correct, so we generate assembly first and then run it through an external assembler, just like it is already done for Android builds.
- Linker is invoked via "g++" command instead of "gcc": g++ passes the appropriate magic parameters to the linker, which ensure correct registration of stack unwind tables in dynamic libraries.
This commit removes the "super_*" functions from
typeck::infer::combine, and adds them as default methods on the
Combine trait instead, making it possible to remove a lot of
boilerplate from the various impls of Combine.
I've been wanting to do this for over a year. In fact, it was my
original motivation for default methods!
It might be possible to tighten things up even more, but this is the
bulk of it.
For #7083.
The metadata issue with the old version is now fixed. Ready for review.
This is also not the full solution to #7083, because this is not supported yet:
```
trait Foo : Send { }
impl <T: Send> Foo for T { }
fn foo<T: Foo>(val: T, chan: std::comm::Chan<T>) {
chan.send(val);
}
```
cc @nikomatsakis
Given that bootstrapping and running the testsuite works without
exporting discriminant values as global constants, I conclude that
they're unused and can be removed.
This commit removes the "super_*" functions from
typeck::infer::combine, and adds them as default methods on the
Combine trait instead, making it possible to remove a lot of
boilerplate from the various impls of Combine.
I've been wanting to do this for over a year. In fact, it was my
original motivation for default methods!
It might be possible to tighten things up even more, but this is the
bulk of it.
The first commit message is pretty good, but whomever reviews this should probably also at least glance at the changes I made in LLVM. I basically reorganized our pending patch queue to be a bit more organized and clearer in what needs to go where. After this, our queue would be:
* Add the `no-split-stack` attribute
* Add the `fixedstacksegment` attribute
* Add split-stacks for arm android
* Add split-stacks for arm linux
* Add split stacks for mips
Then there's a patch which I added to get rust to build at all on LLVM-head, and I'm not quite sure why it's there, but nothing seems to be crashing for now! (famous last words).
Otherwise, I just updated code to reflect the changes I made in LLVM with the only major change being the advent of the new `no_split_stack` attribute. This is work towards #1226, but someone more familiar with the code should probably actually assign the attribute to the appropriate functions.
Also as a bonus, I've verified that this closes#5774
That is, there was lots more hacking than the other more-mechanical
ports Felix did.
There's also a strange pattern that I hacked in to accommodate the
Outer/Inner traversal structure of the existing code (which was
previously encoding this by untying the Y-combinator style knot of the
vtable, and then retying it but superimposing new methods that "stop
at items"). I hope either I or someone else can come back in the
future and replace this ugliness with something more natural.
Added boilerplate macro; all the OuterLint definitions are the same
(but must be abstracted over implementing struct, thus the macro).
Revised lint.rs use declarations to make ast references explicit.
Also removed unused imports.
Given that bootstrapping and running the testsuite works without
exporting discriminant values as global constants, I conclude that
they're unused and can be removed.
This requires changes to method search and to codegen. We now emit a
vtable for objects that includes methods from all supertraits.
Closes#4100.
Also, actually populate the cache for vtables, and also key it by type
so that it actually works.
When using a `do` block to call an internal iterator, if you forgot to
return a value from the body, it would tell you
error: Do-block body must return bool, but returns () here. Perhaps
you meant to write a `for`-loop?
This advice no longer applies as `for` loops are now for external
iterators. Delete this message outright and let it use the default error
message
error: mismatched types: expected `bool` but found `()`
r? @thestinger
Pointers to bound variables shouldn't be stored before checking pattern,
otherwise piped patterns can conflict with each other (issue #6338).
Closes#6338.
This pull request includes support for generic functions and self arguments in methods, and combinations thereof. This also encompasses any kind of trait methods, regular and static, with and without default implementation. The implementation is backed up by a felt ton of test cases `:)`
This is a very important step towards being able to compile larger programs with debug info, since practically any generic function caused an ICE before.
One point worth discussing is that activating debug info now automatically (and silently) sets the `no_monomorphic_collapse` flag. Otherwise debug info would show wrong type names in all but one instance of the monomorphized function.
Another thing to note is that the handling of generic types does not strictly follow the DWARF specification. That is, variables with type `T` (where `T=int`) are described as having type `int` and not as having type `T`. In other words, we are losing information whether a variable has been declared with a type parameter as its type. In practice this should not make much of difference though since the concrete type is mostly what one is interested in. I'll post an issue later so this won't be forgotten.
Also included are a number of bug fixes:
* Closes#1758
* Closes#8513
* Closes#8443
* Fixes handling of field names in tuple structs
* Fixes and re-enables test case for option-like enums that relied on undefined behavior before
* Closes#1339 (should have been closed a while ago)
Cheers,
Michael
When using a `do` block to call an internal iterator, if you forgot to
return a value from the body, it would tell you
error: Do-block body must return bool, but returns () here. Perhaps
you meant to write a `for`-loop?
This advice no longer applies as `for` loops are now for external
iterators. Delete this message outright and let it use the default error
message
error: mismatched types: expected `bool` but found `()`
Retry of PR #8471
Replace the remaining functions marked for issue #8228 with similar functions that are iterator-based.
Change `either::{lefts, rights}` to be iterator-filtering instead of returning a vector.
Replace `map_vec`, `map_vec2`, `iter_vec2` in std::result with three functions:
* `result::collect` gathers `Iterator<Result<V, U>>` to `Result<~[V], U>`
* `result::fold` folds `Iterator<Result<T, E>>` to `Result<V, E>`
* `result::fold_` folds `Iterator<Result<T, E>>` to `Result<(), E>`
Pointers to bound variables shouldn't be stored before checking pattern,
otherwise piped patterns can conflict with each other (issue #6338).
Closes#6338.
Rewriting visit.rs to operate on a borrowed `&mut V` where `<V:Visitor>`
r? @nikomatsakis
r? @pcwalton
This is the first in a planned series of incremental pull requests. (There will probably be five pull requests including this one, though they can be combined or split as necessary.)
Part of #7081. (But definitely does *not* complete it, not on its own, and not even after all five parts land; there are still a few loose ends to tie up or trim afterwards.)
The bulk of this change for this particular PR is pnkfelix@3d83010, which has the changes necessary to visit.rs to support everything else that comes later. The other commits are illustrating the standard mechanical transformation that I am applying.
One important point for nearly *all* of these pull requests: I was deliberately *not* trying to be intelligent in the transformation.
* My goal was to minimize code churn, and make the transformation as mechanical as possible.
* For example, I kept the separation between the Visitor struct (corresponding to the earlier vtable of functions that were potentially closed over local state) and the explicitly passed (and clones) visitor Env. I am certain that this is almost always unnecessary, and a later task will be to go through an meld the Env's into the Visitors as appropriate. (My original goal had been to make such melding part of this task; that's why I turned them into a (Env, vtable) tuple way back when. But I digress.)
* Also, my main goal here was to get rid of the record of `@fn`'s as described by the oldvisit.rs API. (This series gets rid of all but one such case; I'm still investigating that.) There is *still* plenty of `@`-boxing left to be removed, I'm sure, and even still some `@fn`'s too; removing all of those is not the goal here; its just to get rid of the encoded protocol of `@fn`'s in the (old)visit API.
To see where things will be going in the future (i.e., to get a sneak-preview of future pull-requests in the series), see:
* https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step1 (that's this one)
* https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step2
* https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step3
* https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step4
* https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step5
* Note that between step 4 and step 5 there is just a single commit, but its a doozy because its the only case where my mechanical transformation did not apply, and thus more serious rewriting was necessary. See commit pnkfelix@da902b2ff3b1e0bee9fc63cf00c449cceea8abf7
If they are on the trait then it is extremely annoying to use them as
generic parameters to a function, e.g. with the iterator param on the trait
itself, if one was to pass an Extendable<int> to a function that filled it
either from a Range or a Map<VecIterator>, one needs to write something
like:
fn foo<E: Extendable<int, Range<int>> +
Extendable<int, Map<&'self int, int, VecIterator<int>>>
(e: &mut E, ...) { ... }
since using a generic, i.e. `foo<E: Extendable<int, I>, I: Iterator<int>>`
means that `foo` takes 2 type parameters, and the caller has to specify them
(which doesn't work anyway, as they'll mismatch with the iterators used in
`foo` itself).
This patch changes it to:
fn foo<E: Extendable<int>>(e: &mut E, ...) { ... }
LLVMConstStringInContext() doesn't need a null-terminated string. It
takes a length instead. Using .to_c_str() here triggers an ICE whenever
the string literal embeds a null, as in "\x00".
.with_c_str() is a replacement for the old .as_c_str(), to avoid
unnecessary boilerplate.
Replace all usages of .to_c_str().with_ref() with .with_c_str().
Alpha-renamed top-level visit_* functions to walk_*.
(Motivation: Distinguish visit action and recursive traversal.)
Abstract over `&mut self` rather than over `@mut self`.
This required some acrobatics, notably the
`impl<E> Visitor<E> for @mut Visitor<E>`
and corresponding introduction of `@mut Visitor` and some local `let
mut` bindings.
Remove oldvisit reference.
Added default implementations for all of the Visitor trait methods.
Note that both `visit_expr_post` and `visit_ty` are no-op's by
default, just like they are in `oldvisit::default_visitor`.
Refactoring: extract logic to ease swapping visit for oldvisit (hopefully).
Replace these with three functions based on iterators: collect, fold,
and fold_. The mapping part is replaced by iterator .map(), so the part
that these functions do is to accumulate the final Result<,> value.
* `result::collect` gathers `Iterator<Result<V, U>>` to `Result<~[V], U>`
* `result::fold` folds `Iterator<Result<T, E>>` to `Result<V, E>`
* `result::fold_` folds `Iterator<Result<T, E>>` to `Result<(), E>`
Remove the only use of either::partition since it was better
accomplished with vector methods.
Update either::partition so that it sizes the vectors correctly before
it starts.
While looking over the code for object coercion, I realized that it wasn't quite handling freezing and reborrowing correctly. Tweak the code, adding tests for the relevant cases.
r? @pcwalton
This pull request re-implements handling of visibility scopes and source code positions in debug info. It should now be very stable and properly handle
+ variable shadowing
+ expanded code (macros and the new for-loop de-sugaring, for example)
+ variables in the middle of nested scopes
+ bindings declared in the head of match statement arms.
all of which did not work at all or did not work reliably before. Those interested in a more detailed description of the problems at hand, I kindly refer to http://michaelwoerister.github.io/2013/08/03/visibility-scopes.html
Why doesn't the `populate_scope_map()` function use `syntax::visit`?
Because it would not improve this particular AST walker (see: 69dc790849 (commitcomment-3781426))
Cheers,
Michael
Adds `--target-cpu` flag which lets you choose a more specific target cpu instead of just passing the default, `generic`. It's more or less akin to `-mcpu`/`-mtune` in clang/gcc.
Also cleanup the treatment of mutability in mem_categorization, which still
included the concept of interior mutability. At some point, we should
refactor the types to exclude the possibility of interior mutability rather
than just ignoring the mutability value in those cases.
to favor inherent methods over extension methods.
The reason to favor inherent methods is that otherwise an impl
like
impl Foo for @Foo { fn method(&self) { self.method() } }
causes infinite recursion. The current change to favor inherent methods is
rather hacky; the method resolution code is in need of a refactoring.
what amount a T* pointer must be adjusted to reach the contents
of the box. For `~T` types, this requires knowing the type `T`,
which is not known in the case of objects.
This can be applied to statics and it will indicate that LLVM will attempt to
merge the constant in .data with other statics.
I have preliminarily applied this to all of the statics generated by the new
`ifmt!` syntax extension. I compiled a file with 1000 calls to `ifmt!` and a
separate file with 1000 calls to `fmt!` to compare the sizes, and the results
were:
```
fmt 310k
ifmt (before) 529k
ifmt (after) 202k
```
This now means that ifmt! is both faster and smaller than fmt!, yay!