bors [Wed, 23 Nov 2016 17:16:22 +0000 (11:16 -0600)]
Auto merge of #36449 - canndrew:expand_is_uninhabited, r=eddyb
Expand is_uninhabited
This allows code such as this to compile:
``` rust
let x: ! = ...;
match x {};
let y: (u32, !) = ...;
match y {};
```
@eddyb You were worried about making this change. Do you have any idea about what could break? Are there any special tests that need to be written for it?
Guillaume Gomez [Wed, 23 Nov 2016 11:18:09 +0000 (12:18 +0100)]
Rollup merge of #37760 - nnethercote:TypeWalker-SmallVector, r=arielb1
Type walker small vector
These two changes avoid allocations on some hot paths and speed up a few workloads (some from rustc-benchmarks, as well as the workload from #36799) by 1--2%.
Guillaume Gomez [Wed, 23 Nov 2016 11:18:09 +0000 (12:18 +0100)]
Rollup merge of #37442 - estebank:cast-deref-hint, r=jonathandturner
Provide hint when cast needs a dereference
For a given code:
``` rust
vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
```
display:
``` nocode
error: casting `&f64` as `i16` is invalid
--> file3.rs:2:35
|
2 | vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
| - ^^^
| |
| did you mean `*s`?
```
instead of:
``` nocode
error: casting `&f64` as `i16` is invalid
--> <anon>:2:30
|
2 | vec![0.0].iter().map(|s| s as i16).collect();
| ^^^^^^^^
|
= help: cast through a raw pointer first
```
bors [Wed, 23 Nov 2016 07:21:45 +0000 (01:21 -0600)]
Auto merge of #37886 - Stebalien:set-perm, r=alexcrichton
Add a method for setting permissions directly on an open file.
On unix like systems, the underlying file corresponding to any given path may change at any time. This function makes it possible to set the permissions of the a file corresponding to a `File` object even if its path changes.
@retep998, what's the best way to do this on Windows? I looked into `SetFileInformationByHandle` but couldn't find a way to do it atomically risking clobbering access time information.
This is a first step towards fixing #37885. This function doesn't *have* to be public but this is useful functionality that should probably be exposed.
bors [Tue, 22 Nov 2016 23:51:59 +0000 (17:51 -0600)]
Auto merge of #37487 - goffrie:break, r=nikomatsakis
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop.
- ~~I have also changed the loop scoping in MIR-building so that the test
of a while loop is not considered to be part of that loop. This makes
the rules consistent with #37360. The new loop scopes in typeck also
follow this rule. That means that `loop { while (break) {} }` now
terminates instead of looping forever. This is technically a breaking
change.~~
- ~~On that note, expressions like `while break {}` and `if break {}` no
longer parse because `{}` is interpreted as an expression argument to
`break`. But no code except compiler test cases should do that anyway
because it makes no sense.~~
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
Steven Allen [Sat, 19 Nov 2016 17:53:54 +0000 (09:53 -0800)]
Add a method for setting permissions directly on an open file.
On unix like systems, the underlying file corresponding to any given path may
change at any time. This function makes it possible to set the permissions of
the a file corresponding to a `File` object even if its path changes.
bors [Tue, 22 Nov 2016 09:29:46 +0000 (03:29 -0600)]
Auto merge of #37834 - bluss:peek-none, r=BurntSushi
Make Peekable remember peeking a None
Peekable should remember if a None has been seen in the `.peek()` method.
It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the
underlying iterator at most once. This does not by itself make the iterator
fused.
Thanks to @s3bk for the code in `fn peek()` itself.
Geoffry Song [Sat, 29 Oct 2016 22:15:06 +0000 (15:15 -0700)]
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
bors [Tue, 22 Nov 2016 03:15:48 +0000 (21:15 -0600)]
Auto merge of #37602 - jseyfried:directory_ownership, r=nikomatsakis
parser: simplify directory ownership semantics
This PR simplifies the semantics of "directory ownership". After this PR,
- a non-inline module without a `#[path]` attribute (e.g. `mod foo;`) is allowed iff its parent module/block (whichever is nearer) is a directory owner,
- an non-inline module is a directory owner iff its corresponding file is named `mod.rs` (c.f. [comment](https://github.com/rust-lang/rust/issues/32401#issuecomment-201021902)),
- a block is never a directory owner (c.f. #31534), and
- an inline module is a directory owner iff either
- its parent module/block is a directory owner (again, c.f. #31534), or
- it has a `#[path]` attribute (c.f. #36789).
These semantics differ from today's in three orthogonal ways:
- `#[path = "foo.rs"] mod foo;` is no longer a directory owner. This is a [breaking-change].
- #36789 is generalized to apply to modules that are not directory owners in addition to blocks.
- A macro-expanded non-inline module is only allowed where an ordinary non-inline module would be allowed. Today, we incorrectly allow macro-expanded non-inline modules in modules that are not directory owners (but not in blocks). This is a [breaking-change].
bors [Mon, 21 Nov 2016 23:59:10 +0000 (17:59 -0600)]
Auto merge of #37642 - nnethercote:no-HirVec-of-P, r=michaelwoerister
Change HirVec<P<T>> to HirVec<T> in hir:: Expr.
This PR changes data structures like this:
```
[ ExprArray | 8 | P ]
|
v
[ P | P | P | P | P | P | P | P ]
|
v
[ ExprTup | 2 | P ]
|
v
[ P | P ]
|
v
[ Expr ]
```
to this:
```
[ ExprArray | 8 | P ]
|
v
[ [ ExprTup | 2 | P ] | ... ]
|
v
[ Expr | Expr ]
```
I thought this would be a win for #36799, and on a cut-down version of that workload this reduces the peak heap size (as measured by Massif) from 885 MiB to 875 MiB. However, the peak RSS as measured by `-Ztime-passes` and by `/usr/bin/time` increases by about 30 MiB.
I'm not sure why. Just look at the picture above -- the second data structure clearly takes up less space than the first. My best idea relates to unused elements in the slices. `HirVec<Expr>` is a typedef for `P<[Expr]>`. If there were any unused excess elements then I could see that memory usage would increase, because those excess elements are larger in `HirVec<Expr>` than in `HirVec<P<Expr>>`. But AIUI there are no such excess elements, and Massif's measurements corroborate that.
However, the two main creation points for these data structures are these lines from `lower_expr`:
```rust
ExprKind::Vec(ref exprs) => {
hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
}
ExprKind::Tup(ref elts) => {
hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
}
```
I suspect what is happening is that temporary excess elements are created within the `collect` calls. The workload from #36799 has many 2-tuples and 3-tuples and when `Vec` gets doubled it goes from a capacity of 1 to 4, which would lead to excess elements. Though, having said that, `Vec::with_capacity` doesn't create excess AFAICT. So I'm not sure. What goes on inside `collect` is complex.
Anyway, in its current form this PR is a memory consumption regression and so not worth landing but I figured I'd post it in case anyone has additional insight.
This changes structures like this:
```
[ ExprArray | 8 | P ]
|
v
[ P | P | P | P | P | P | P | P ]
|
v
[ ExprTup | 2 | P ]
|
v
[ P | P ]
|
v
[ Expr ]
```
to this:
```
[ ExprArray | 8 | P ]
|
v
[ [ ExprTup | 2 | P ] | ... ]
|
v
[ Expr | Expr ]
```
bors [Mon, 21 Nov 2016 20:37:24 +0000 (14:37 -0600)]
Auto merge of #37677 - jsen-:master, r=alexcrichton
libstd: support creation of anonymous pipe on WinXP/2K3
`PIPE_REJECT_REMOTE_CLIENTS` flag is not supported on Windows < VISTA, and every invocation of `anon_pipe` including attempts to pipe `std::process::Child`'s stdio fails.
This PR should work around this issue by performing a runtime check of windows version and conditionally omitting this flag on "XP and friends".
Getting the version should be probably moved out of the function `anon_pipe` itself (the OS version does not often change during runtime :) ), but:
- I didn't find any precedent for this and assuming there's not much overhead (I hope windows does not perform any heuristics to find out it's own version, just fills couple of fields in the struct).
- the code path is not especially performance sensitive anyway.
bors [Mon, 21 Nov 2016 14:08:47 +0000 (08:08 -0600)]
Auto merge of #37824 - jseyfried:symbols, r=eddyb
Clean up `ast::Attribute`, `ast::CrateConfig`, and string interning
This PR
- removes `ast::Attribute_` (changing `Attribute` from `Spanned<Attribute_>` to a struct),
- moves a `MetaItem`'s name from the `MetaItemKind` variants to a field of `MetaItem`,
- avoids needlessly wrapping `ast::MetaItem` with `P`,
- moves string interning into `syntax::symbol` (`ast::Name` is a reexport of `symbol::Symbol` for now),
- replaces `InternedString` with `Symbol` in the AST, HIR, and various other places, and
- refactors `ast::CrateConfig` from a `Vec` to a `HashSet`.
bors [Sun, 20 Nov 2016 23:06:53 +0000 (17:06 -0600)]
Auto merge of #37888 - bluss:chars-count, r=alexcrichton
Improve .chars().count()
Use a simpler loop to count the `char` of a string: count the
number of non-continuation bytes. Use `count += <conditional>` which the
compiler understands well and can apply loop optimizations to.
benchmark descriptions and results for two configurations:
- ascii: ascii text
- cy: cyrillic text
- jp: japanese text
- words ascii: counting each split_whitespace item from the ascii text
- words jp: counting each split_whitespace item from the jp text
I briefly explored a more involved blocked algorithm (looking at 8 or more bytes at a time),
but the code in this PR was always winning `count_words_ascii` in particular (counting
many small strings); this solution is an improvement without tradeoffs.
Guillaume Gomez [Sun, 20 Nov 2016 14:00:05 +0000 (15:00 +0100)]
Rollup merge of #37881 - ollie27:rustdoc_stab_enum_macro, r=alexcrichton
rustdoc: Remove unnecessary stability versions
For some reason only on enum and macro pages, the stability version is
rendered after the summary unlike all other pages. As it is already
displayed at the top of the page for all items, this removes it for
consistency and to prevent it from overlapping the summary text.
bors [Sun, 20 Nov 2016 02:01:52 +0000 (20:01 -0600)]
Auto merge of #37833 - sfackler:process-abort, r=alexcrichton
Add std::process::abort
This calls libc abort on Unix and fastfail on Windows, first running
cleanups to do things like flush stdout buffers. This matches with libc
abort's behavior, which flushes open files.
Esteban Küber [Fri, 28 Oct 2016 02:02:27 +0000 (19:02 -0700)]
Provide hint when cast needs a dereference
For a given code:
```rust
vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
```
display:
```nocode
error: casting `&f64` as `i16` is invalid
--> foo.rs:2:35
|
2 | vec![0.0].iter().map(|s| s as i16).collect::<Vec<i16>>();
| - ^^^ cannot cast `&f64` as `i16`
| |
| did you mean `*s`?
```
instead of:
```nocode
error: casting `&f64` as `i16` is invalid
--> <anon>:2:30
|
2 | vec![0.0].iter().map(|s| s as i16).collect();
| ^^^^^^^^
|
= help: cast through a raw pointer first
```
Ulrik Sverdrup [Sat, 19 Nov 2016 22:18:43 +0000 (23:18 +0100)]
str: Improve .chars().count()
Use a simpler loop to count the `char` of a string: count the
number of non-continuation bytes. Use `count += <conditional>` which the
compiler understands well and can apply loop optimizations to.
The librustc_llvm API remains mostly unchanged, except that llvm::Attribute is no longer a bitflag but represents only a *single* attribute.
The ability to store many attributes in a small number of bits and modify them without interacting with LLVM is only used in rustc_trans::abi and closely related modules, and only attributes for function arguments are considered there.
Thus rustc_trans::abi now has its own bit-packed representation of argument attributes, which are translated to rustc_llvm::Attribute when applying the attributes.
Currently using `--test` with a crate that contains a `#[proc_macro_derive]` attribute causes an error. This PR doesn't attempt to fix the issue itself, or determine what tesing of a proc_macro_derive crate should be - just to provide a better error message.
Oliver Middleton [Sat, 19 Nov 2016 17:22:33 +0000 (17:22 +0000)]
rustdoc: Remove unnecessary stability versions
For some reason only on enum and macro pages, the stability version is
rendered after the summary unlike all other pages. As it is already
displayed at the top of the page for all items, this removes it for
consistency and to prevent it from overlapping the summary text.
bors [Sat, 19 Nov 2016 16:08:26 +0000 (08:08 -0800)]
Auto merge of #37822 - cuviper:llvm-link-shared, r=alexcrichton
rustbuild: allow dynamically linking LLVM
The makefiles and `mklldeps.py` called `llvm-config --shared-mode` to
find out if LLVM defaulted to shared or static libraries, and just went
with that. But under rustbuild, `librustc_llvm/build.rs` was assuming
that LLVM should be static, and even forcing `--link-static` for 3.9+.
Now that build script also uses `--shared-mode` to learn the default,
which should work better for pre-3.9 configured for dynamic linking, as
it wasn't possible back then to choose differently via `llvm-config`.
Further, the configure script now has a new `--enable-llvm-link-shared`
option, which allows one to manually override `--link-shared` on 3.9+
instead of forcing static.
Update: There are now four static/shared scenarios that can happen
for the supported LLVM versions:
- 3.9+: By default use `llvm-config --link-static`
- 3.9+ and `--enable-llvm-link-shared`: Use `--link-shared` instead.
- 3.8: Use `llvm-config --shared-mode` and go with its answer.
- 3.7: Just assume static, maintaining the status quo.
bors [Sat, 19 Nov 2016 12:58:48 +0000 (04:58 -0800)]
Auto merge of #37814 - japaric:aapcs, r=alexcrichton
fix `extern "aapcs" fn`
to actually use the AAPCS calling convention
closes #37810
This is technically a [breaking-change] because it changes the ABI of
`extern "aapcs"` functions that (a) involve `f32`/`f64` arguments/return
values and (b) are compiled for arm-eabihf targets from
"aapcs-vfp" (wrong) to "aapcs" (correct).
Appendix:
What these ABIs mean?
- In the "aapcs-vfp" ABI or "hard float" calling convention: Floating
point values are passed/returned through FPU registers (s0, s1, d0, etc.)
- Whereas, in the "aapcs" ABI or "soft float" calling convention:
Floating point values are passed/returned through general purpose
registers (r0, r1, etc.)
Mixing these ABIs can cause problems if the caller assumes that the
routine is using one of these ABIs but it's actually using the other
one.
---
r? @alexcrichton We are going this `extern "aapcs" fn` thing to implement some intrinsics (floatundidf) for the eabihf targets in order to comply with LLVM's calling convention of intrinsics.
Oh, and the value of the enum came from [here](http://llvm.org/docs/doxygen/html/namespacellvm_1_1CallingConv.html).